kimjunhan commited on
Commit
dec7e7d
·
verified ·
1 Parent(s): 9014606

Add files using upload-large-folder tool

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. third_party/ktx-src/tests/loadtests/appfwSDL/AppBaseSDL.cpp +138 -0
  2. third_party/ktx-src/tests/loadtests/appfwSDL/AppBaseSDL.h +85 -0
  3. third_party/ktx-src/tests/loadtests/appfwSDL/GLAppSDL.cpp +330 -0
  4. third_party/ktx-src/tests/loadtests/appfwSDL/GLAppSDL.h +59 -0
  5. third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/VulkanAppSDL.cpp +1748 -0
  6. third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/VulkanAppSDL.h +172 -0
  7. third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/VulkanContext.cpp +363 -0
  8. third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/VulkanContext.h +134 -0
  9. third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/VulkanSwapchain.cpp +434 -0
  10. third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/VulkanSwapchain.h +105 -0
  11. third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/mac/vulkan/README.md +8 -0
  12. third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/mac/vulkan/explicit_layer.d/VkLayer_khronos_validation.json +1709 -0
  13. third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/mac/vulkan/icd.d/MoltenVK_icd.json +8 -0
  14. third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/shaders/textoverlay.frag +16 -0
  15. third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/shaders/textoverlay.vert +20 -0
  16. third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/vulkancheckres.h +48 -0
  17. third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/vulkandebug.cpp +288 -0
  18. third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/vulkandebug.h +106 -0
  19. third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/vulkantextoverlay.hpp +839 -0
  20. third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/vulkantools.cpp +918 -0
  21. third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/vulkantools.h +312 -0
  22. third_party/ktx-src/tests/loadtests/appfwSDL/main.cpp +96 -0
  23. third_party/ktx-src/tests/loadtests/common/LoadTestSample.cpp +330 -0
  24. third_party/ktx-src/tests/loadtests/common/LoadTestSample.h +91 -0
  25. third_party/ktx-src/tests/loadtests/common/SwipeDetector.cpp +146 -0
  26. third_party/ktx-src/tests/loadtests/common/SwipeDetector.h +200 -0
  27. third_party/ktx-src/tests/loadtests/common/TranscodeTargetStrToFmt.cpp +61 -0
  28. third_party/ktx-src/tests/loadtests/common/TranscodeTargetStrToFmt.h +16 -0
  29. third_party/ktx-src/tests/loadtests/common/disable_glm_warnings.h +21 -0
  30. third_party/ktx-src/tests/loadtests/common/ltexceptions.h +66 -0
  31. third_party/ktx-src/tests/loadtests/common/models/cube.obj +63 -0
  32. third_party/ktx-src/tests/loadtests/common/models/sphere.obj +2503 -0
  33. third_party/ktx-src/tests/loadtests/common/models/teapot.dae +0 -0
  34. third_party/ktx-src/tests/loadtests/common/models/torusknot.obj +0 -0
  35. third_party/ktx-src/tests/loadtests/common/reenable_warnings.h +18 -0
  36. third_party/ktx-src/tests/loadtests/common/vecmath.hpp +448 -0
  37. third_party/ktx-src/tests/loadtests/compile_shader.cmake +80 -0
  38. third_party/ktx-src/tests/loadtests/geom/cube.h +72 -0
  39. third_party/ktx-src/tests/loadtests/geom/cube_data.h +155 -0
  40. third_party/ktx-src/tests/loadtests/geom/frame.h +23 -0
  41. third_party/ktx-src/tests/loadtests/geom/quad.h +34 -0
  42. third_party/ktx-src/tests/loadtests/glloadtests.cmake +449 -0
  43. third_party/ktx-src/tests/loadtests/glloadtests/GLLoadTests.cpp +313 -0
  44. third_party/ktx-src/tests/loadtests/glloadtests/GLLoadTests.h +100 -0
  45. third_party/ktx-src/tests/loadtests/glloadtests/gles1/DrawTexture.cpp +250 -0
  46. third_party/ktx-src/tests/loadtests/glloadtests/gles1/DrawTexture.h +66 -0
  47. third_party/ktx-src/tests/loadtests/glloadtests/gles1/ES1LoadTests.cpp +109 -0
  48. third_party/ktx-src/tests/loadtests/glloadtests/gles1/TexturedCube.cpp +202 -0
  49. third_party/ktx-src/tests/loadtests/glloadtests/gles1/TexturedCube.h +38 -0
  50. third_party/ktx-src/tests/loadtests/glloadtests/resources/ios/Info.plist.in +50 -0
third_party/ktx-src/tests/loadtests/appfwSDL/AppBaseSDL.cpp ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* -*- tab-width: 4; -*- */
2
+ /* vi: set sw=2 ts=4 expandtab: */
3
+
4
+ /* $Id: f63e0a9e6eed51ed84a8eea1eff0708c8a6af22b $ */
5
+
6
+ /*
7
+ * Copyright 2015-2020 Mark Callow.
8
+ * SPDX-License-Identifier: Apache-2.0
9
+ */
10
+
11
+ /**
12
+ * @internal
13
+ * @file
14
+ * @~English
15
+ *
16
+ * @brief Base class for SDL applications.
17
+ */
18
+
19
+ #include "AppBaseSDL.h"
20
+ #include <iomanip>
21
+ #include <sstream>
22
+ #include <iostream>
23
+
24
+ bool
25
+ AppBaseSDL::initialize(Args& /*args*/)
26
+ {
27
+ const char* basePath = SDL_GetBasePath();
28
+ // SDL_GetBasePath returns directory of the app, except for
29
+ // iOS & macOS app bundles where it returns the Resources
30
+ // directory.
31
+ if (basePath == NULL)
32
+ basePath = SDL_strdup("./");
33
+ sBasePath = basePath;
34
+ #if SDL_PLATFORM_LINUX
35
+ // TODO figure out best way to handle these resources
36
+ sBasePath += "../resources/";
37
+ #endif
38
+ #if SDL_PLATFORM_WINDOWS
39
+ // Ditto
40
+ sBasePath += "resources/";
41
+ #endif
42
+ return true;
43
+ }
44
+
45
+
46
+ void
47
+ AppBaseSDL::initializeFPSTimer()
48
+ {
49
+ lastFrameTime = 0;
50
+ fpsCounter.numFrames = 0;
51
+ fpsCounter.lastFPS = 0;
52
+ startTicks = fpsCounter.startTicks = SDL_GetPerformanceCounter();
53
+ }
54
+
55
+
56
+ void
57
+ AppBaseSDL::finalize() {
58
+
59
+ }
60
+
61
+
62
+ bool
63
+ AppBaseSDL::doEvent(SDL_Event* event)
64
+ {
65
+ switch (event->type) {
66
+ case SDL_EVENT_QUIT:
67
+ finalize();
68
+ exit(0);
69
+ }
70
+ return true;
71
+ }
72
+
73
+
74
+ void
75
+ AppBaseSDL::onFPSUpdate()
76
+ {
77
+
78
+ }
79
+
80
+
81
+ // Protected, non-virtual
82
+ void
83
+ AppBaseSDL::drawFrame()
84
+ {
85
+ ticks_t ticks = SDL_GetPerformanceCounter();
86
+ Uint64 tps = SDL_GetPerformanceFrequency();
87
+ uint32_t msTicksSinceStart = (uint32_t)((ticks - startTicks) * 1000 / tps);
88
+
89
+ drawFrame(msTicksSinceStart);
90
+
91
+ ticks_t endTicks = SDL_GetPerformanceCounter();
92
+ lastFrameTime = (1000.0f * (endTicks - ticks)) / tps;
93
+ fpsCounter.numFrames++;
94
+ if (endTicks - fpsCounter.startTicks > tps) {
95
+ fpsCounter.lastFPS = (float)(fpsCounter.numFrames * tps)
96
+ / (endTicks - fpsCounter.startTicks);
97
+ onFPSUpdate(); // Notify listeners that fps value has been updated.
98
+ fpsCounter.startTicks = endTicks;
99
+ fpsCounter.numFrames = 0;
100
+ }
101
+ }
102
+
103
+ //----------------------------------------------------------------------
104
+ // Window title and text overlay functions
105
+ //----------------------------------------------------------------------
106
+
107
+
108
+ void
109
+ AppBaseSDL::setAppTitle(const char* const szExtra)
110
+ {
111
+ appTitle = name();
112
+ if (szExtra != NULL && szExtra[0] != '\0') {
113
+ appTitle += ": ";
114
+ appTitle += szExtra;
115
+ }
116
+ setWindowTitle();
117
+ }
118
+
119
+
120
+ void
121
+ AppBaseSDL::setWindowTitle()
122
+ {
123
+ std::stringstream ss;
124
+ std::string wt;
125
+
126
+ ss << std::fixed << std::setprecision(2)
127
+ << lastFrameTime << "ms (" << fpsCounter.lastFPS << " fps)" << " ";
128
+ wt = ss.str();
129
+ wt += appTitle;
130
+ SDL_SetWindowTitle(pswMainWindow, wt.c_str());
131
+ }
132
+
133
+
134
+ const char* appName()
135
+ {
136
+ return theApp->name();
137
+ }
138
+
third_party/ktx-src/tests/loadtests/appfwSDL/AppBaseSDL.h ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* -*- tab-width: 4; -*- */
2
+ /* vi: set sw=2 ts=4 expandtab: */
3
+
4
+ #ifndef APP_BASE_SDL_H_1456211087
5
+ #define APP_BASE_SDL_H_1456211087
6
+
7
+ /* $Id: f63e0a9e6eed51ed84a8eea1eff0708c8a6af22b $ */
8
+
9
+ /*
10
+ * Copyright 2015-2020 Mark Callow.
11
+ * SPDX-License-Identifier: Apache-2.0
12
+ */
13
+
14
+ /**
15
+ * @internal
16
+ * @file
17
+ * @~English
18
+ *
19
+ * @brief Declarations for App framework using SDL.
20
+ */
21
+
22
+ #include <SDL3/SDL.h>
23
+ #include <string>
24
+ #include <vector>
25
+
26
+ class AppBaseSDL {
27
+ public:
28
+ typedef Uint64 ticks_t;
29
+ typedef std::vector<std::string> Args;
30
+ AppBaseSDL(const char* const name) : szName(name), appTitle(name) { }
31
+ virtual bool initialize(Args& args);
32
+ virtual void finalize();
33
+ // Ticks in milliseconds since start.
34
+ virtual void drawFrame(uint32_t) { }
35
+ // When used with SDL_SetEventWatch, return value is ignored. When used
36
+ // with SDL_SetEventFilter, 1 causes event to be added to SDL's internal
37
+ // event queue, 0 causes it to be dropped.
38
+ virtual bool doEvent(SDL_Event* event);
39
+ virtual void onFPSUpdate();
40
+ virtual SDL_Window* getMainWindow() { return pswMainWindow; }
41
+
42
+ void drawFrame();
43
+ void initializeFPSTimer();
44
+ const char* name() { return szName; }
45
+ const std::string getAssetPath() { return sBasePath; }
46
+
47
+ // Sets title to be used on window title bar. Content of szExtra ia
48
+ // appended to the app name.
49
+ virtual void setAppTitle(const char* const szExtra);
50
+
51
+ static bool onEvent(void* userdata, SDL_Event* event) {
52
+ return ((AppBaseSDL *)userdata)->doEvent(event);
53
+ }
54
+
55
+ static void onDrawFrame(void* userdata) {
56
+ ((AppBaseSDL *)userdata)->drawFrame();
57
+ }
58
+
59
+ protected:
60
+ // Sets text on window title bar. Fps value is preprended to appTitle.
61
+ virtual void setWindowTitle();
62
+
63
+ ticks_t startTicks;
64
+ float lastFrameTime; // ms
65
+ struct fpsCounter {
66
+ ticks_t startTicks;
67
+ int numFrames;
68
+ float lastFPS;
69
+ } fpsCounter;
70
+
71
+ SDL_Window* pswMainWindow;
72
+
73
+ const char* const szName;
74
+ std::string appTitle;
75
+ std::string sBasePath;
76
+
77
+ };
78
+
79
+ extern class AppBaseSDL* theApp;
80
+
81
+ #endif /* APP_BASE_SDL_H_1456211087 */
82
+
83
+
84
+
85
+
third_party/ktx-src/tests/loadtests/appfwSDL/GLAppSDL.cpp ADDED
@@ -0,0 +1,330 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* -*- tab-width: 4; -*- */
2
+ /* vi: set sw=2 ts=4 expandtab: */
3
+
4
+ /* $Id: ac63511da134f2c25a9e1da86a36bc27b6198ae3 $ */
5
+
6
+ /*
7
+ * Copyright 2015-2020 Mark Callow.
8
+ * SPDX-License-Identifier: Apache-2.0
9
+ */
10
+
11
+ /**
12
+ * @internal
13
+ * @file
14
+ * @~English
15
+ *
16
+ * @brief GLAppSDL app class.
17
+ */
18
+
19
+ #if defined(_WIN32)
20
+ #if _MSC_VER < 1900
21
+ #define snprintf _snprintf
22
+ #endif
23
+ #define _CRT_SECURE_NO_WARNINGS
24
+ #define WIN32_LEAN_AND_MEAN
25
+ #include "windows.h"
26
+ #include "GL/glew.h"
27
+ #include "SDL3/SDL_loadso.h"
28
+ #else
29
+ #define GL_GLEXT_PROTOTYPES 1
30
+ #include "GL/glcorearb.h" // for glEnable and FRAMEBUFFER_RGB
31
+ #endif
32
+
33
+ #include <stdio.h>
34
+ #include <iomanip>
35
+ #include <sstream>
36
+
37
+ #include "GLAppSDL.h"
38
+
39
+ #if SDL_PLATFORM_WINDOWS
40
+ void setWindowsIcon(SDL_Window *sdlWindow);
41
+ #endif
42
+
43
+ bool
44
+ GLAppSDL::initialize(Args& args)
45
+ {
46
+ if (!AppBaseSDL::initialize(args))
47
+ return false;
48
+
49
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, profile);
50
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, majorVersion);
51
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minorVersion);
52
+ // On SDL3 this defaults to 8. On SDL2 it was 0.
53
+ SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0);
54
+ #if !defined(EMSCRIPTEN)
55
+ if (majorVersion >= 3)
56
+ SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, 1);
57
+ #endif
58
+ #if defined(DEBUG) && !defined(EMSCRIPTEN)
59
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
60
+ #endif
61
+
62
+ if (profile == SDL_GL_CONTEXT_PROFILE_ES) {
63
+ #if 0
64
+ int numVideoDrivers = SDL_GetNumVideoDrivers();
65
+ int i;
66
+ const char** drivers;
67
+
68
+ drivers = (const char**)SDL_malloc(sizeof(const char*) * numVideoDrivers);
69
+ for (i = 0; i < numVideoDrivers; i++) {
70
+ drivers[i] = SDL_GetVideoDriver(i);
71
+ }
72
+ #endif
73
+
74
+ // Only the indicated platforms pay attention to these hints
75
+ // but they could be set on any platform.
76
+ #if SDL_PLATFORM_WINDOWS || SDL_PLATFORM_LINUX
77
+ SDL_SetHint(SDL_HINT_OPENGL_ES_DRIVER, "1");
78
+ #endif
79
+
80
+ #if SDL_PLATFORM_WINDOWS
81
+ // If using ANGLE copied from Chrome should set to "d3dcompiler_46.dll"
82
+ // Should set value via compiler -D definition from gyp file.
83
+ SDL_SetHint(SDL_HINT_VIDEO_WIN_D3DCOMPILER, "none");
84
+ #endif
85
+ }
86
+
87
+ SDL_SetHint(SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK, "1");
88
+ // CAUTION: Setting this to 0 (the default) on macOS causes loss of all touch events
89
+ // from a trackpad not just those corresponding to mouse clicks.
90
+ SDL_SetHint(SDL_HINT_MOUSE_TOUCH_EVENTS, "1");
91
+
92
+ #if 0
93
+ const char* mt = SDL_GetHint(SDL_HINT_MOUSE_TOUCH_EVENTS);
94
+ SDL_Log("MOUSE_TOUCH_EVENTS = %s", mt);
95
+ const char* tm = SDL_GetHint(SDL_HINT_TOUCH_MOUSE_EVENTS);
96
+ SDL_Log("TOUCH_MOUSE_EVENTS = %s", tm);
97
+ const char* tto = SDL_GetHint(SDL_HINT_TRACKPAD_IS_TOUCH_ONLY);
98
+ SDL_Log("TRACKPAD_IS_TOUCH_ONLY = %s", tto);
99
+ #endif
100
+
101
+ pswMainWindow = SDL_CreateWindow(
102
+ szName,
103
+ w_width, w_height,
104
+ SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
105
+ );
106
+
107
+ if (pswMainWindow == NULL) {
108
+ (void)SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, szName, SDL_GetError(), NULL);
109
+ return false;
110
+ }
111
+ #if SDL_PLATFORM_WINDOWS
112
+ // Set the application's own icon in place of the Windows default set by SDL.
113
+ // Needs to be done here to avoid change being visible.
114
+ setWindowsIcon(pswMainWindow);
115
+ #endif
116
+
117
+ sgcGLContext = SDL_GL_CreateContext(pswMainWindow);
118
+ // Work around bug in SDL. It returns a 2.x context when 3.x is requested.
119
+ // It does though internally record an error.
120
+ const char* error = SDL_GetError();
121
+ if (sgcGLContext == NULL
122
+ || (error[0] != '\0'
123
+ && majorVersion >= 3
124
+ && (profile == SDL_GL_CONTEXT_PROFILE_CORE
125
+ || profile == SDL_GL_CONTEXT_PROFILE_COMPATIBILITY))
126
+ ) {
127
+ (void)SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, szName, SDL_GetError(), NULL);
128
+ return false;
129
+ }
130
+
131
+ #if SDL_PLATFORM_WINDOWS
132
+ if (profile != SDL_GL_CONTEXT_PROFILE_ES)
133
+ {
134
+ // No choice but to use GLEW for GL on Windows; there is no .lib with static
135
+ // bindings. For ES we use one of the hardware vendor SDKs all of which have
136
+ // static bindings.
137
+ // TODO: Figure out how to support {GLX,WGL}_EXT_create_context_es2_profile
138
+ // were there are no static bindings. Need a GLEW equivalent for ES and
139
+ // different compile options. Perhaps can borrow function loading stuff
140
+ // from SDL's testgles2.c.
141
+
142
+ // So one build of this library can be linked in to applications using GLEW and
143
+ // applications not using GLEW, do not call any GLEW functions directly.
144
+ // Call via queried function pointers.
145
+ SDL_SharedObject* glewdll;
146
+ #if defined(_DEBUG)
147
+ glewdll = SDL_LoadObject("glew32d.dll");
148
+ // KTX-Software repo only contains non-debug library for x64 hence this.
149
+ if (glewdll == NULL) {
150
+ glewdll = SDL_LoadObject("glew32.dll");
151
+ }
152
+ #else
153
+ glewdll = SDL_LoadObject("glew32.dll");
154
+ #endif
155
+ if (glewdll == NULL) {
156
+ std::string sName(szName);
157
+
158
+ (void)SDL_ShowSimpleMessageBox(
159
+ SDL_MESSAGEBOX_ERROR,
160
+ szName,
161
+ SDL_GetError(),
162
+ NULL);
163
+ return false;
164
+ }
165
+
166
+ typedef GLenum(GLEWAPIENTRY PFNGLEWINIT)(void);
167
+ typedef const GLubyte * GLEWAPIENTRY PFNGLEWGETERRORSTRING(GLenum error);
168
+ PFNGLEWINIT* pGlewInit;
169
+ PFNGLEWGETERRORSTRING* pGlewGetErrorString = nullptr;
170
+ bool loadError = true;
171
+ #define STR(s) #s
172
+ #if defined(_M_IX86)
173
+ /* Win32 GLEW uses __stdcall. */
174
+ #define DNAMESTR(x,n) STR(_##x##@##n)
175
+ #else
176
+ /* x64 uses __cdecl. */
177
+ #define DNAMESTR(x,n) STR(x)
178
+ #endif
179
+ pGlewInit = (PFNGLEWINIT*)SDL_LoadFunction(glewdll, DNAMESTR(glewInit,0));
180
+ if (pGlewInit != NULL) {
181
+ pGlewGetErrorString = (PFNGLEWGETERRORSTRING*)SDL_LoadFunction(
182
+ glewdll, DNAMESTR(glewGetErrorString,4));
183
+ if (pGlewGetErrorString != NULL) {
184
+ loadError = false;
185
+ }
186
+ }
187
+
188
+ if (loadError) {
189
+ std::string sName(szName);
190
+
191
+ (void)SDL_ShowSimpleMessageBox(
192
+ SDL_MESSAGEBOX_ERROR,
193
+ szName,
194
+ SDL_GetError(),
195
+ NULL);
196
+ return false;
197
+ }
198
+ int iResult = pGlewInit();
199
+ if (iResult != GLEW_OK) {
200
+ std::string sName(szName);
201
+
202
+ (void)SDL_ShowSimpleMessageBox(
203
+ SDL_MESSAGEBOX_ERROR,
204
+ szName,
205
+ (const char*)pGlewGetErrorString(iResult),
206
+ NULL);
207
+ return false;
208
+ }
209
+ }
210
+ #endif
211
+
212
+ int srgb;
213
+ SDL_GL_GetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, &srgb);
214
+ if (srgb && profile != SDL_GL_CONTEXT_PROFILE_ES)
215
+ glEnable(GL_FRAMEBUFFER_SRGB);
216
+
217
+ // In case the window is created with a different size than specified.
218
+ int actualWidth, actualHeight;
219
+ SDL_GetWindowSizeInPixels(pswMainWindow, &actualWidth, &actualHeight);
220
+ resizeWindow(actualWidth, actualHeight);
221
+
222
+ initializeFPSTimer();
223
+ return true;
224
+ }
225
+
226
+
227
+ void
228
+ GLAppSDL::finalize()
229
+ {
230
+ SDL_GL_DestroyContext(sgcGLContext);
231
+ }
232
+
233
+
234
+ bool
235
+ GLAppSDL::doEvent(SDL_Event* event)
236
+ {
237
+ switch (event->type) {
238
+ case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
239
+ resizeWindow(event->window.data1, event->window.data2);
240
+ return 0;
241
+ break;
242
+ }
243
+ return AppBaseSDL::doEvent(event);
244
+ }
245
+
246
+
247
+ void
248
+ GLAppSDL::drawFrame(uint32_t /*msTicks*/)
249
+ {
250
+ SDL_GL_SwapWindow(pswMainWindow);
251
+ }
252
+
253
+
254
+ void
255
+ GLAppSDL::windowResized()
256
+ {
257
+ // Derived class can override as necessary.
258
+ }
259
+
260
+
261
+ void
262
+ GLAppSDL::resizeWindow(int width, int height)
263
+ {
264
+ w_width = width;
265
+ w_height = height;
266
+ windowResized();
267
+ }
268
+
269
+
270
+ void
271
+ GLAppSDL::onFPSUpdate()
272
+ {
273
+ // Using onFPSUpdate avoids rewriting the title every frame.
274
+ setWindowTitle();
275
+ }
276
+
277
+ #if 0
278
+ void
279
+ GLAppSDL::setAppTitle(const char* const szExtra)
280
+ {
281
+ appTitle = name();
282
+ if (szExtra != NULL && szExtra[0] != '\0') {
283
+ appTitle += ": ";
284
+ appTitle += szExtra;
285
+ }
286
+ setWindowTitle();
287
+ }
288
+
289
+
290
+ void
291
+ GLAppSDL::setWindowTitle(const char* const szExtra)
292
+ {
293
+ std::stringstream ss;
294
+
295
+ ss << std::fixed << std::setprecision(2)
296
+ << lastFrameTime << "ms (" << fpsCounter.lastFPS << " fps)"
297
+ << " - " << szName;
298
+
299
+ if (szExtra != NULL && szExtra[0] != '\0') {
300
+ ss << ": " << szExtra;
301
+ }
302
+ SDL_SetWindowTitle(pswMainWindow, ss.str().c_str());
303
+ }
304
+
305
+ void
306
+ GLAppSDL::setWindowTitle()
307
+ {
308
+ SDL_SetWindowTitle(pswMainWindow, appTitle.c_str());
309
+ }
310
+ #endif
311
+
312
+ #if SDL_PLATFORM_WINDOWS
313
+ // Windows specific code to use icon in module
314
+ void
315
+ setWindowsIcon(SDL_Window *sdlWindow) {
316
+ HINSTANCE handle = ::GetModuleHandle(nullptr);
317
+ // Identify icon by name rather than IDI_ macro to avoid having to
318
+ // include application's resource.h.
319
+ HICON icon = ::LoadIcon(handle, "MAIN_ICON");// MAKEINTRESOURCE(IDI_ICON1));
320
+ if (icon != nullptr){
321
+ HWND hwnd = (HWND)SDL_GetPointerProperty(SDL_GetWindowProperties(sdlWindow), SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL);
322
+ if (hwnd) {
323
+ ::SetClassLongPtr(hwnd, GCLP_HICON, reinterpret_cast<LONG_PTR>(icon));
324
+ }
325
+ }
326
+ }
327
+ #endif
328
+
329
+ // }
330
+
third_party/ktx-src/tests/loadtests/appfwSDL/GLAppSDL.h ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* -*- tab-width: 4; -*- */
2
+ /* vi: set sw=2 ts=4 expandtab: */
3
+
4
+ #ifndef GL_APP_SDL_H_1456211188
5
+ #define GL_APP_SDL_H_1456211188
6
+
7
+ /* $Id: ac63511da134f2c25a9e1da86a36bc27b6198ae3 $ */
8
+
9
+ /*
10
+ * Copyright 2015-2020 Mark Callow.
11
+ * SPDX-License-Identifier: Apache-2.0
12
+ */
13
+
14
+ /**
15
+ * @internal
16
+ * @file
17
+ * @~English
18
+ *
19
+ * @brief Declaration of GLAppSDL base class for GL apps.
20
+ */
21
+
22
+ #include "AppBaseSDL.h"
23
+
24
+
25
+ class GLAppSDL : public AppBaseSDL {
26
+ public:
27
+ GLAppSDL(const char* const name,
28
+ int width, int height,
29
+ const SDL_GLProfile profile,
30
+ const int majorVersion,
31
+ const int minorVersion)
32
+ : AppBaseSDL(name),
33
+ profile(profile),
34
+ majorVersion(majorVersion), minorVersion(minorVersion)
35
+ {
36
+ appTitle = name;
37
+ w_width = width;
38
+ w_height = height;
39
+ };
40
+ virtual bool doEvent(SDL_Event* event);
41
+ virtual void drawFrame(uint32_t msTicks);
42
+ virtual void finalize();
43
+ virtual bool initialize(Args& args);
44
+ virtual void onFPSUpdate();
45
+ virtual void resizeWindow(int width, int height);
46
+ virtual void windowResized();
47
+
48
+ protected:
49
+ SDL_GLContext sgcGLContext;
50
+
51
+ int w_width;
52
+ int w_height;
53
+
54
+ const SDL_GLProfile profile;
55
+ const int majorVersion;
56
+ const int minorVersion;
57
+ };
58
+
59
+ #endif /* GL_APP_SDL_H_1456211188 */
third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/VulkanAppSDL.cpp ADDED
@@ -0,0 +1,1748 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* -*- tab-width: 4; -*- */
2
+ /* vi: set sw=2 ts=4 expandtab: */
3
+
4
+ /*
5
+ * Copyright 2017-2020 Mark Callow.
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+
9
+ /**
10
+ * @internal
11
+ * @class VulkanAppSDL
12
+ * @~English
13
+ *
14
+ * @brief Framework for Vulkan apps using SDL windows.
15
+ *
16
+ * @author Mark Callow, github.com/MarkCallow.
17
+ */
18
+
19
+
20
+ #if defined(_WIN32)
21
+ #if _MSC_VER < 1900
22
+ #define snprintf _snprintf
23
+ #endif
24
+ #define _CRT_SECURE_NO_WARNINGS
25
+ #endif
26
+
27
+ #include <assert.h>
28
+ #include <stdio.h>
29
+ #include <string.h>
30
+ #include <iomanip>
31
+ #include <string>
32
+ #include <sstream>
33
+
34
+ #include "VulkanAppSDL.h"
35
+
36
+ // Include this when vulkantools is removed.
37
+ //#include "vulkancheckres.h"
38
+
39
+ #define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
40
+
41
+ #define ERROR_RETURN(msg) \
42
+ (void)SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, szName, msg, NULL); \
43
+ return false;
44
+
45
+ #define WARNING(msg) \
46
+ (void)SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_WARNING, szName, msg, NULL);
47
+
48
+ #define GET_INSTANCE_PROC_ADDR(inst, entrypoint) \
49
+ { \
50
+ pfn##entrypoint = \
51
+ (PFN_vk##entrypoint)vkGetInstanceProcAddr(inst, "vk" #entrypoint); \
52
+ if (pfn##entrypoint == NULL) { \
53
+ ERROR_RETURN("vkGetInstanceProcAddr: unable to find vk" #entrypoint); \
54
+ } \
55
+ }
56
+
57
+ #define GET_DEVICE_PROC_ADDR(device, entrypoint) \
58
+ { \
59
+ pfn##entrypoint = \
60
+ (PFN_vk##entrypoint)vkGetDeviceProcAddr(device, "vk" #entrypoint); \
61
+ if (pfn##entrypoint == NULL) { \
62
+ ERROR_RETURN("vkGetDeviceProcAddr: unable to find vk" #entrypoint); \
63
+ } \
64
+ }
65
+
66
+ #if SDL_PLATFORM_WINDOWS
67
+ void setWindowsIcon(SDL_Window *sdlWindow);
68
+ #endif
69
+
70
+ VulkanAppSDL::~VulkanAppSDL()
71
+ {
72
+
73
+ }
74
+
75
+
76
+ bool
77
+ VulkanAppSDL::initialize(Args& args)
78
+ {
79
+ for (uint32_t i = 1; i < args.size(); i++) {
80
+ if (args[i].compare("--validate") == 0) {
81
+ validate = true;
82
+ args.erase(args.begin() + i);
83
+ break;
84
+ }
85
+ }
86
+ if (!AppBaseSDL::initialize(args))
87
+ return false;
88
+
89
+ SDL_SetHint(SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK, "1");
90
+ // CAUTION: Setting this to 0 (the default) on macOS causes loss of all touch events
91
+ // from a trackpad not just those corresponding to mouse clicks.
92
+ SDL_SetHint(SDL_HINT_MOUSE_TOUCH_EVENTS, "1");
93
+ // Create window.
94
+ // Vulkan samples do not pass any information from Vulkan initialization
95
+ // to window creation so creating the window first should be ok...
96
+ pswMainWindow = SDL_CreateWindow(
97
+ szName,
98
+ w_width, w_height,
99
+ SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY
100
+ );
101
+
102
+ if (pswMainWindow == NULL) {
103
+ (void)SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, szName,
104
+ SDL_GetError(), NULL);
105
+ return false;
106
+ }
107
+
108
+ #if SDL_PLATFORM_WINDOWS
109
+ // Set the application's own icon in place of the Windows default set by SDL.
110
+ // Needs to be done here to avoid change being visible.
111
+ setWindowsIcon(pswMainWindow);
112
+ #endif
113
+
114
+ if (!initializeVulkan()) {
115
+ return false;
116
+ }
117
+
118
+ initializeFPSTimer();
119
+ return true;
120
+ }
121
+
122
+
123
+ void
124
+ VulkanAppSDL::finalize()
125
+ {
126
+ if (vkctx.descriptorPool)
127
+ {
128
+ vkctx.device.destroyDescriptorPool(vkctx.descriptorPool, nullptr);
129
+ }
130
+ vkDestroyPipelineCache((VkDevice)vkctx.device, vkctx.pipelineCache, nullptr);
131
+
132
+ vkctx.swapchain.cleanup();
133
+ for (auto& shaderModule : shaderModules)
134
+ {
135
+ vkctx.device.destroyShaderModule(shaderModule);
136
+ }
137
+ if (enableTextOverlay)
138
+ {
139
+ delete textOverlay;
140
+ }
141
+
142
+ vkctx.device.destroyCommandPool(vkctx.commandPool);
143
+ //vkctx.device.destroy();
144
+ if (vsSurface != VK_NULL_HANDLE) {
145
+ // Destroy
146
+ }
147
+ //vkctx.instance.destroy();
148
+ }
149
+
150
+
151
+ bool
152
+ VulkanAppSDL::doEvent(SDL_Event* event)
153
+ {
154
+ switch (event->type) {
155
+ case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
156
+ resizeWindow(event->window.data1, event->window.data2);
157
+ return 0;
158
+ break;
159
+ }
160
+ return AppBaseSDL::doEvent(event);
161
+ }
162
+
163
+
164
+ void
165
+ VulkanAppSDL::drawFrame(uint32_t /*msTicks*/)
166
+ {
167
+ if (!prepared)
168
+ return;
169
+
170
+ prepareFrame();
171
+
172
+ vkctx.drawCmdSubmitInfo.commandBufferCount = 1;
173
+ vkctx.drawCmdSubmitInfo.pCommandBuffers =
174
+ &vkctx.drawCmdBuffers[currentBuffer];
175
+
176
+ // Submit to queue
177
+ VK_CHECK_RESULT(vkQueueSubmit(vkctx.queue, 1,
178
+ &vkctx.drawCmdSubmitInfo, VK_NULL_HANDLE));
179
+
180
+ submitFrame();
181
+ }
182
+
183
+
184
+ void
185
+ VulkanAppSDL::windowResized()
186
+ {
187
+ // Derived class can override as necessary.
188
+ }
189
+
190
+ void
191
+ VulkanAppSDL::resizeWindow(int width, int height)
192
+ {
193
+ // XXX Necessary? Get out-of-date errors from vkAcquireNextImage regardless
194
+ // of whether this guard is used. This guard doesn't seem to make them any
195
+ // less likely.
196
+ #define GUARD 0
197
+ #if GUARD
198
+ if (!prepared)
199
+ {
200
+ return;
201
+ }
202
+ prepared = false;
203
+ #endif
204
+
205
+ // Recreate swap chain.
206
+
207
+ w_width = width;
208
+ w_height = height;
209
+
210
+ // This destroys any existing swapchain and makes a new one.
211
+ createSwapchain();
212
+
213
+ vkDestroyImageView(vkctx.device, vkctx.depthBuffer.view, nullptr);
214
+ vkDestroyImage(vkctx.device, vkctx.depthBuffer.image, nullptr);
215
+ vkFreeMemory(vkctx.device, vkctx.depthBuffer.mem, nullptr);
216
+
217
+ // Recreate the frame buffers
218
+ for (uint32_t i = 0; i < vkctx.framebuffers.size(); i++)
219
+ {
220
+ vkDestroyFramebuffer(vkctx.device, vkctx.framebuffers[i], nullptr);
221
+ }
222
+
223
+ // XXX Is this necessary? Is Willems doing this?
224
+ vkDestroyRenderPass(vkctx.device, vkctx.renderPass, NULL);
225
+
226
+ vkctx.destroyPresentCommandBuffers();
227
+ (void)(prepareDepthBuffer() // XXX Call it DepthStencil?
228
+ && vkctx.createPresentCommandBuffers()
229
+ && preparePresentCommandBuffers()
230
+ && prepareRenderPass()
231
+ && prepareFramebuffers());
232
+
233
+ flushInitialCommands();
234
+ if (enableTextOverlay)
235
+ {
236
+ textOverlay->reallocateCommandBuffers();
237
+ updateTextOverlay();
238
+ }
239
+ // Notify derived class.
240
+ windowResized();
241
+ #if GUARD
242
+ prepared = true;
243
+ #endif
244
+ }
245
+
246
+
247
+ void
248
+ VulkanAppSDL::onFPSUpdate()
249
+ {
250
+ if (!enableTextOverlay) {
251
+ setWindowTitle();
252
+ }
253
+ updateTextOverlay();
254
+ // Using onFPSUpdate avoids rewriting the title every frame.
255
+ }
256
+
257
+
258
+ //----------------------------------------------------------------------
259
+ // Frame draw utilities
260
+ //----------------------------------------------------------------------
261
+
262
+
263
+ void
264
+ VulkanAppSDL::prepareFrame()
265
+ {
266
+ // Acquire the next image from the swap chain
267
+ VkResult err;
268
+ err = vkctx.swapchain.acquireNextImage(semaphores.presentComplete,
269
+ &currentBuffer);
270
+
271
+ if (err == VK_ERROR_OUT_OF_DATE_KHR) {
272
+ // Swap chain is out of date (e.g. the window was resized).
273
+ // Re-create it.
274
+ //resize();
275
+ //draw(demo);
276
+ return;
277
+ } else if (err == VK_SUBOPTIMAL_KHR) {
278
+ // demo->swapchain is not as optimal as it could be, but the platform's
279
+ // presentation engine will still present the image correctly.
280
+ } else {
281
+ assert(!err);
282
+ }
283
+
284
+ // Submit post present image barrier to transform the image back to a
285
+ // color attachment that our render pass can write to
286
+ VkSubmitInfo submitInfo = {};
287
+ submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
288
+ submitInfo.pNext = NULL;
289
+ submitInfo.commandBufferCount = 1;
290
+ submitInfo.pCommandBuffers = &vkctx.postPresentCmdBuffers[currentBuffer];
291
+ VK_CHECK_RESULT(vkQueueSubmit(vkctx.queue, 1,
292
+ &submitInfo, VK_NULL_HANDLE));
293
+ }
294
+
295
+
296
+ void
297
+ VulkanAppSDL::submitFrame()
298
+ {
299
+ bool submitTextOverlay = enableTextOverlay && textOverlay->visible;
300
+
301
+ if (submitTextOverlay)
302
+ {
303
+ // Wait for color attachment output to finish before rendering the
304
+ // text overlay
305
+ VkPipelineStageFlags stageFlags
306
+ = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
307
+ vkctx.drawCmdSubmitInfo.pWaitDstStageMask = &stageFlags;
308
+
309
+ // Set semaphores
310
+ // Wait for render complete semaphore
311
+ vkctx.drawCmdSubmitInfo.waitSemaphoreCount = 1;
312
+ vkctx.drawCmdSubmitInfo.pWaitSemaphores = &semaphores.renderComplete;
313
+ // Signal ready with text overlay complete semaphore
314
+ vkctx.drawCmdSubmitInfo.signalSemaphoreCount = 1;
315
+ vkctx.drawCmdSubmitInfo.pSignalSemaphores
316
+ = &semaphores.textOverlayComplete;
317
+
318
+ // Submit current text overlay command buffer
319
+ vkctx.drawCmdSubmitInfo.commandBufferCount = 1;
320
+ vkctx.drawCmdSubmitInfo.pCommandBuffers
321
+ = &textOverlay->cmdBuffers[currentBuffer];
322
+ VK_CHECK_RESULT(vkQueueSubmit(vkctx.queue, 1, &vkctx.drawCmdSubmitInfo,
323
+ VK_NULL_HANDLE));
324
+
325
+ // Reset stage mask
326
+ vkctx.drawCmdSubmitInfo.pWaitDstStageMask = &vkctx.submitPipelineStages;
327
+ // Reset wait and signal semaphores for rendering next frame
328
+ // Wait for swap chain presentation to finish
329
+ vkctx.drawCmdSubmitInfo.waitSemaphoreCount = 1;
330
+ vkctx.drawCmdSubmitInfo.pWaitSemaphores = &semaphores.presentComplete;
331
+ // Signal ready with offscreen semaphore
332
+ vkctx.drawCmdSubmitInfo.signalSemaphoreCount = 1;
333
+ vkctx.drawCmdSubmitInfo.pSignalSemaphores = &semaphores.renderComplete;
334
+ }
335
+ // Submit pre-present image barrier to transform the image from color
336
+ // attachment to present(khr) for presenting to the swap chain.
337
+ VkSubmitInfo submitInfo = {};
338
+ submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
339
+ submitInfo.pNext = NULL;
340
+ submitInfo.commandBufferCount = 1;
341
+ submitInfo.pCommandBuffers = &vkctx.prePresentCmdBuffers[currentBuffer];
342
+ VK_CHECK_RESULT(vkQueueSubmit(vkctx.queue, 1, &submitInfo, VK_NULL_HANDLE));
343
+
344
+ VkResult err =
345
+ vkctx.swapchain.queuePresent(vkctx.queue, currentBuffer,
346
+ submitTextOverlay ?
347
+ semaphores.textOverlayComplete : semaphores.renderComplete);
348
+
349
+ if (err == VK_ERROR_OUT_OF_DATE_KHR) {
350
+ // swapchain is out of date (e.g. the window was resized) and
351
+ // must be recreated:
352
+ //resize();
353
+ } else if (err == VK_SUBOPTIMAL_KHR) {
354
+ if (!subOptimalPresentWarned) {
355
+ SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_WARNING, szName,
356
+ "Suboptimal present of framebuffer.",
357
+ NULL);
358
+ }
359
+ } else
360
+ assert(!err);
361
+
362
+ // This is necessary because the text overlay's command buffer changes
363
+ // every frame and, although the other command buffers are the same
364
+ // every frame, they aren't marked for simultaneous use.
365
+ VK_CHECK_RESULT(vkQueueWaitIdle(vkctx.queue));
366
+ }
367
+
368
+
369
+ //----------------------------------------------------------------------
370
+ // Vulkan Initialization
371
+ //----------------------------------------------------------------------
372
+
373
+
374
+ bool
375
+ VulkanAppSDL::initializeVulkan()
376
+ {
377
+ if (createInstance()
378
+ && findGpu()
379
+ && setupDebugReporting()
380
+ && vkctx.swapchain.connectInstance(vkctx.instance, vkctx.gpu)
381
+ && createSurface()
382
+ && createDevice()
383
+ && vkctx.swapchain.connectDevice(vkctx.device)
384
+ && createSemaphores()
385
+ && createSwapchain()
386
+ && prepareDepthBuffer()
387
+ && vkctx.createPresentCommandBuffers()
388
+ && preparePresentCommandBuffers()
389
+ && prepareRenderPass()
390
+ && createPipelineCache()
391
+ && prepareFramebuffers()) {
392
+ // Functions above most likely generate pipeline commands
393
+ // that need to be flushed before beginning the render loop.
394
+ flushInitialCommands();
395
+ prepareTextOverlay();
396
+
397
+ return true;
398
+ } else {
399
+ return false;
400
+ }
401
+ }
402
+
403
+
404
+ bool
405
+ VulkanAppSDL::createInstance()
406
+ {
407
+ MAYBE_UNUSED VkResult err;
408
+ uint32_t instanceLayerCount = 0;
409
+ std::vector<const char *>* instanceValidationLayers = nullptr;
410
+
411
+ std::vector<const char *> instanceValidationLayers_alt1 = {
412
+ "VK_LAYER_KHRONOS_validation"
413
+ };
414
+
415
+ std::vector<const char *> instanceValidationLayers_alt2 = {
416
+ "VK_LAYER_LUNARG_standard_validation"
417
+ };
418
+
419
+ // Look for validation layers.
420
+ bool validationFound = 0;
421
+ if (validate) {
422
+ err = vkEnumerateInstanceLayerProperties(&instanceLayerCount, NULL);
423
+ assert(err == VK_SUCCESS);
424
+
425
+ if (instanceLayerCount > 0) {
426
+ VkLayerProperties* instanceLayers
427
+ = new VkLayerProperties[instanceLayerCount];
428
+ err = vkEnumerateInstanceLayerProperties(&instanceLayerCount,
429
+ instanceLayers);
430
+ assert(err == VK_SUCCESS);
431
+
432
+ validationFound = checkLayers(
433
+ (uint32_t)instanceValidationLayers_alt1.size(),
434
+ instanceValidationLayers_alt1.data(),
435
+ instanceLayerCount,
436
+ instanceLayers);
437
+ if (validationFound) {
438
+ instanceValidationLayers = &instanceValidationLayers_alt1;
439
+ } else {
440
+ // Use alternative set of validation layers.
441
+ validationFound = checkLayers(
442
+ (uint32_t)instanceValidationLayers_alt2.size(),
443
+ instanceValidationLayers_alt2.data(),
444
+ instanceLayerCount,
445
+ instanceLayers);
446
+ instanceValidationLayers = &instanceValidationLayers_alt2;
447
+ }
448
+ if (validationFound) {
449
+ for (uint32_t i = 0; i < instanceValidationLayers->size(); i++)
450
+ {
451
+ deviceValidationLayers.push_back(
452
+ instanceValidationLayers->data()[i]);
453
+ }
454
+ }
455
+ delete [] instanceLayers;
456
+ }
457
+
458
+ if (!validationFound) {
459
+ WARNING("vkEnumerateInstanceLayerProperties failed to find "
460
+ "requested validation layers.\n");
461
+ }
462
+ }
463
+
464
+
465
+ /* Build list of needed extensions */
466
+ uint32_t rec;
467
+ const char* const* requiredExtensionNames = SDL_Vulkan_GetInstanceExtensions(&rec);
468
+ if (requiredExtensionNames == nullptr) {
469
+ std::string title;
470
+ std::stringstream msg;
471
+ title = szName;
472
+ title += ": SDL_Vulkan_GetInstanceExtensions Failure";
473
+ msg << "Could not retrieve instance extensions: "
474
+ << SDL_GetError();
475
+
476
+ (void)SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, title.c_str(),
477
+ msg.str().c_str(), NULL);
478
+ return false;
479
+ }
480
+
481
+ // Find out if device_properties2 is available. If so, enable it
482
+ // as it is required for ASTC HDR and also if we later find we
483
+ // are running on a Portability Subset device.
484
+ std::vector<vk::ExtensionProperties> availableExtensions =
485
+ vk::enumerateInstanceExtensionProperties(nullptr);
486
+ for (auto& extension : availableExtensions) {
487
+ if (!strncmp(extension.extensionName,
488
+ VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
489
+ VK_MAX_EXTENSION_NAME_SIZE)) {
490
+ extensionNames.push_back(
491
+ VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME
492
+ );
493
+ }
494
+ #if VK_KHR_portability_subset
495
+ if (!strncmp(extension.extensionName,
496
+ VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME,
497
+ VK_MAX_EXTENSION_NAME_SIZE)) {
498
+ extensionNames.push_back(
499
+ VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME
500
+ );
501
+ }
502
+ #endif
503
+ }
504
+
505
+ if (validate)
506
+ extensionNames.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
507
+
508
+ for (uint32_t i = 0; i < rec; i++) {
509
+ extensionNames.push_back(requiredExtensionNames[i]);
510
+ }
511
+
512
+ const vk::ApplicationInfo app(szName, 0, szName, 0, vkVersion);
513
+
514
+ vk::InstanceCreateInfo instanceInfo(
515
+ {},
516
+ &app,
517
+ (uint32_t)deviceValidationLayers.size(),
518
+ (const char *const *)deviceValidationLayers.data(),
519
+ (uint32_t)extensionNames.size(),
520
+ (const char *const *)extensionNames.data());
521
+ #if VK_KHR_portability_subset
522
+ instanceInfo.setFlags(vk::InstanceCreateFlagBits::eEnumeratePortabilityKHR);
523
+ #endif
524
+
525
+ /*
526
+ * This is info for a temp callback to use during CreateInstance.
527
+ * After the instance is created, we use the instance-based
528
+ * function to register the final callback.
529
+ */
530
+ VkDebugReportCallbackCreateInfoEXT dbgCreateInfo = { };
531
+ if (validate) {
532
+ dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
533
+ dbgCreateInfo.pNext = NULL;
534
+ dbgCreateInfo.pfnCallback = debugFunc;
535
+ dbgCreateInfo.pUserData = this;
536
+ dbgCreateInfo.flags =
537
+ VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT
538
+ | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
539
+ //| VK_DEBUG_REPORT_INFORMATION_BIT_EXT
540
+ //| VK_DEBUG_REPORT_DEBUG_BIT_EXT;
541
+ instanceInfo.pNext = &dbgCreateInfo;
542
+ }
543
+
544
+ //err = vkCreateInstance(&instanceInfo, NULL, &vkctx.instance);
545
+ vk::Result cerr;
546
+ cerr = vk::createInstance(&instanceInfo, nullptr, &vkctx.instance);
547
+
548
+ if (cerr != vk::Result::eSuccess) {
549
+ std::string title;
550
+ std::stringstream msg;
551
+ title = szName;
552
+ title += ": vkCreateInstance Failure";
553
+ if (cerr == vk::Result::eErrorIncompatibleDriver) {
554
+ msg << "Cannot find a compatible Vulkan installable client "
555
+ "driver (ICD).";
556
+ } else if (cerr == vk::Result::eErrorExtensionNotPresent) {
557
+ // Figure out which extension(s) are missing.
558
+ uint32_t instanceExtensionCount = 0;
559
+
560
+ err = vkEnumerateInstanceExtensionProperties(
561
+ NULL,
562
+ &instanceExtensionCount,
563
+ NULL);
564
+ VkExtensionProperties* instanceExtensions
565
+ = new VkExtensionProperties[instanceExtensionCount];
566
+
567
+ assert(err == VK_SUCCESS);
568
+ if (instanceExtensionCount > 0) {
569
+ err = vkEnumerateInstanceExtensionProperties(
570
+ NULL,
571
+ &instanceExtensionCount,
572
+ instanceExtensions);
573
+ assert(err == VK_SUCCESS);
574
+ }
575
+ msg << "Cannot find the following extensions:\n";
576
+ for (uint32_t j = 0; j < extensionNames.size(); j++) {
577
+ uint32_t k;
578
+ for (k = 0; k < instanceExtensionCount; k++) {
579
+ if (!strcmp(extensionNames[j],
580
+ instanceExtensions[k].extensionName))
581
+ break;
582
+ }
583
+ if (k == instanceExtensionCount) {
584
+ // Not found
585
+ msg << " " << extensionNames[j] << "\n";
586
+ }
587
+ }
588
+ msg << "\nMake sure your layers path is set appropriately.";
589
+ delete [] instanceExtensions;
590
+ } else {
591
+ msg << "vkCreateInstance: unexpected failure, code = "
592
+ << cerr << ".\n\nDo you have a compatible Vulkan "
593
+ "installable client driver (ICD) installed?";
594
+ }
595
+ (void)SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, title.c_str(),
596
+ msg.str().c_str(), NULL);
597
+ return false;
598
+ }
599
+
600
+ return true;
601
+ } // createInstance
602
+
603
+
604
+ bool
605
+ VulkanAppSDL::findGpu()
606
+ {
607
+ MAYBE_UNUSED vk::Result err;
608
+ uint32_t gpuCount;
609
+
610
+ // Make initial call to query gpu_count, then second call for gpu info.
611
+ err = vkctx.instance.enumeratePhysicalDevices(&gpuCount,
612
+ (vk::PhysicalDevice*)nullptr);
613
+ assert(err == vk::Result::eSuccess);
614
+
615
+ if (gpuCount > 0) {
616
+ std::vector<vk::PhysicalDevice> gpus;
617
+ gpus.resize(gpuCount);
618
+ err = vkctx.instance.enumeratePhysicalDevices(&gpuCount, gpus.data());
619
+ assert(err == vk::Result::eSuccess);
620
+ // For now just grab the first physical device */
621
+ vkctx.gpu = gpus[0];
622
+ // Store properties and features so apps can query them.
623
+ vkctx.gpu.getProperties(&vkctx.gpuProperties);
624
+ #if 0
625
+ vk::PhysicalDeviceFeatures2 gpuFeatures2;
626
+ vkctx.gpu.getFeatures2(&gpuFeatures2);
627
+ vkctx.gpuFeatures = gpuFeatures2.features;
628
+ #else
629
+ vkctx.gpu.getFeatures(&vkctx.gpuFeatures);
630
+ #endif
631
+ // Get Memory information and properties
632
+ vkctx.gpu.getMemoryProperties(&vkctx.memoryProperties);
633
+
634
+ } else {
635
+ std::string msg;
636
+ ERROR_RETURN(
637
+ "vkEnumeratePhysicalDevices reported zero accessible devices.\n\n"
638
+ "Do you have a compatible Vulkan installable client driver (ICD) "
639
+ "installed?");
640
+ }
641
+
642
+ return true;
643
+ } // findGpu
644
+
645
+
646
+ bool
647
+ VulkanAppSDL::setupDebugReporting()
648
+ {
649
+ if (validate) {
650
+ GET_INSTANCE_PROC_ADDR(vkctx.instance, CreateDebugReportCallbackEXT);
651
+ GET_INSTANCE_PROC_ADDR(vkctx.instance, DestroyDebugReportCallbackEXT);
652
+ GET_INSTANCE_PROC_ADDR(vkctx.instance, DebugReportMessageEXT);
653
+ VkDebugReportCallbackCreateInfoEXT dbgCreateInfo;
654
+ dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
655
+ dbgCreateInfo.pNext = NULL;
656
+ dbgCreateInfo.pfnCallback = debugFunc;
657
+ dbgCreateInfo.pUserData = this;
658
+ dbgCreateInfo.flags =
659
+ VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT;
660
+ VkResult err = pfnCreateDebugReportCallbackEXT(vkctx.instance,
661
+ &dbgCreateInfo, NULL,
662
+ &msgCallback);
663
+ switch (err) {
664
+ case VK_SUCCESS:
665
+ return true;
666
+ break;
667
+ case VK_ERROR_OUT_OF_HOST_MEMORY:
668
+ ERROR_RETURN("CreateDebugReportCallback: out of host memory.");
669
+ break;
670
+ default:
671
+ {
672
+ std::stringstream msg;
673
+ msg << "CreateDebugReportCallback: unexpected failure, result code "
674
+ << err << ".";
675
+ ERROR_RETURN(msg.str().c_str());
676
+ break;
677
+ }
678
+ }
679
+ }
680
+ return true;
681
+ } // setupDebugReporting
682
+
683
+
684
+ bool
685
+ VulkanAppSDL::createSurface()
686
+ {
687
+ vkctx.swapchain.initSurface(pswMainWindow);
688
+ return true;
689
+ } // createSurface
690
+
691
+
692
+ bool
693
+ VulkanAppSDL::createDevice()
694
+ {
695
+ typedef enum { optional, required } ext_need;
696
+ struct extension {
697
+ std::string name;
698
+ ext_need need;
699
+ };
700
+ std::vector<extension> wantedExtensions;
701
+ std::vector<const char*> extensionsToEnable;
702
+
703
+ wantedExtensions.push_back({VK_KHR_SWAPCHAIN_EXTENSION_NAME, required});
704
+ wantedExtensions.push_back({VK_KHR_MAINTENANCE1_EXTENSION_NAME, required});
705
+ #if VK_KHR_portability_subset
706
+ // Portability must be enabled, if present.
707
+ wantedExtensions.push_back({VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME, optional});
708
+ #endif
709
+ // And if present and enabled it requires this to be enabled.
710
+ wantedExtensions.push_back({VK_IMG_FORMAT_PVRTC_EXTENSION_NAME, optional});
711
+ #if VK_EXT_texture_compression_astc_hdr
712
+ wantedExtensions.push_back(
713
+ {VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_EXTENSION_NAME, optional}
714
+ );
715
+ #endif
716
+ #if 0
717
+ wantedExtensions.push_back(
718
+ {TEXTURE_COMPRESSION_ASTC_3D_EXTENSION_NAME, optional}
719
+ );
720
+ #endif
721
+
722
+ vk::Result err;
723
+
724
+ // Figure out if we have the required extensions and remove missing
725
+ // optional extensions from the list. If anyone wonders why we don't
726
+ // just request enablement and ignore the eErrorExtensionNotPresent
727
+ // for optional extensions, 2 answers: the debug layer and (some?) Vulkan
728
+ // implementations crash when you create a command buffer on the affected
729
+ // device.
730
+ uint32_t deviceExtensionCount = 0;
731
+
732
+ err = vkctx.gpu.enumerateDeviceExtensionProperties(
733
+ NULL,
734
+ &deviceExtensionCount,
735
+ (vk::ExtensionProperties*)nullptr);
736
+ assert(err == vk::Result::eSuccess);
737
+
738
+ std::vector<vk::ExtensionProperties> deviceExtensions;
739
+ deviceExtensions.resize(deviceExtensionCount);
740
+
741
+ if (deviceExtensionCount > 0) {
742
+ err = vkctx.gpu.enumerateDeviceExtensionProperties(
743
+ NULL,
744
+ &deviceExtensionCount,
745
+ deviceExtensions.data());
746
+ assert(err == vk::Result::eSuccess);
747
+ }
748
+
749
+ std::vector<std::string> missingExtensions;
750
+ for (uint32_t i = 0; i < wantedExtensions.size(); i++) {
751
+ uint32_t j;
752
+ for (j = 0; j < deviceExtensions.size(); j++) {
753
+ if (!wantedExtensions[i].name.compare(static_cast<const char*>(deviceExtensions[j].extensionName))) {
754
+ extensionsToEnable.push_back(wantedExtensions[i].name.c_str());
755
+ if (!wantedExtensions[i].name.compare(VK_IMG_FORMAT_PVRTC_EXTENSION_NAME)) {
756
+ vkctx.enabledDeviceExtensions.pvrtc = true;
757
+
758
+ }
759
+ #if VK_EXT_texture_compression_astc_hdr
760
+ if (!wantedExtensions[i].name.compare(VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_EXTENSION_NAME)) {
761
+ vkctx.enabledDeviceExtensions.astc_hdr = true;
762
+ }
763
+ #endif
764
+ #if VK_KHR_portability_subset
765
+ if (!wantedExtensions[i].name.compare(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME)) {
766
+ vkctx.gpuIsPortabilitySubsetDevice = true;
767
+ }
768
+ #endif
769
+ break;
770
+ }
771
+ }
772
+ if (j == deviceExtensionCount) {
773
+ // Not found
774
+ if (wantedExtensions[i].need == required) {
775
+ missingExtensions.push_back(wantedExtensions[i].name);
776
+ }
777
+ }
778
+ }
779
+
780
+ if (missingExtensions.size() > 0) {
781
+ std::string title;
782
+ std::stringstream msg;
783
+ std::vector<std::string>::const_iterator it;
784
+
785
+ title = szName;
786
+ title += ": Vulkan Extensions not Found";
787
+ msg << "The following required device extensions were not found:\n";
788
+ for (it = missingExtensions.begin(); it < missingExtensions.end(); it++)
789
+ msg << " " << *it << "\n";
790
+
791
+ msg << "\n\nDo you have a compatible Vulkan "
792
+ "installable client driver (ICD) installed?";
793
+ (void)SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, title.c_str(),
794
+ msg.str().c_str(), NULL);
795
+ return false;
796
+ }
797
+
798
+ float queue_priorities[1] = {0.0};
799
+ const vk::DeviceQueueCreateInfo queueInfo(
800
+ {},
801
+ vkctx.swapchain.queueIndex,
802
+ 1,
803
+ queue_priorities
804
+ );
805
+
806
+ vk::PhysicalDeviceFeatures deviceFeaturesToEnable;
807
+ // Enable specific required and available features here.
808
+ if (vkctx.gpuFeatures.samplerAnisotropy)
809
+ deviceFeaturesToEnable.samplerAnisotropy = true;
810
+ if (vkctx.gpuFeatures.textureCompressionASTC_LDR)
811
+ deviceFeaturesToEnable.textureCompressionASTC_LDR = true;
812
+ if (vkctx.gpuFeatures.textureCompressionBC)
813
+ deviceFeaturesToEnable.textureCompressionBC = true;
814
+ if (vkctx.gpuFeatures.textureCompressionETC2)
815
+ deviceFeaturesToEnable.textureCompressionETC2 = true;
816
+
817
+ #if VK_KHR_portability_subset
818
+ if (vkctx.gpuIsPortabilitySubsetDevice) {
819
+ vk::PhysicalDeviceFeatures2 deviceFeatures;
820
+ deviceFeatures.pNext = &vkctx.gpuPortabilityFeatures;
821
+ vkctx.gpu.getFeatures2(&deviceFeatures);
822
+ }
823
+ #endif
824
+
825
+ #if 0
826
+ // This needs PhysicaldeviceFeaturesToEnable2 and proper understanding of how to
827
+ // navigate a structure chain. Maybe something also was necessary when the
828
+ // gpuFeatures were queried.
829
+ vk::BaseOutStructure* dfs = reinterpret_cast<vk::BaseOutStructure*>(&vkctx.gpuFeatures);
830
+ while (dfs->pNext != NULL) {
831
+ if (dfs->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES_EXT) {
832
+ vk::PhysicalDeviceTextureCompressionASTCHDRFeaturesEXT* ahf = dfs;
833
+ if (afs->textureCompressionASTC_HDR) {
834
+ // Add one of these structs to the requested deviceFeaturesToEnable we
835
+ // are passing in and enable this feature.
836
+ }
837
+ }
838
+ if (dfs->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_3D_FEATURES_EXT) {
839
+ vk::PhysicalDeviceTextureCompressionASTC3DFeaturesEXT* ahf = dfs;
840
+ if (afs->textureCompressionASTC_HDR) {
841
+ // Add one of these structs to the requested deviceFeaturesToEnable we
842
+ // are passing in and enable this feature.
843
+ }
844
+ }
845
+ #endif
846
+
847
+ vk::DeviceCreateInfo deviceInfo(
848
+ {},
849
+ 1,
850
+ &queueInfo,
851
+ (uint32_t)deviceValidationLayers.size(),
852
+ (const char *const *)((validate)
853
+ ? deviceValidationLayers.data()
854
+ : NULL),
855
+ (uint32_t)extensionsToEnable.size(),
856
+ (const char *const *)extensionsToEnable.data(),
857
+ &deviceFeaturesToEnable);
858
+
859
+ #if VK_KHR_portability_subset
860
+ if (vkctx.gpuIsPortabilitySubsetDevice) {
861
+ // Enable all available portability features.
862
+ deviceInfo.pNext = &vkctx.gpuPortabilityFeatures;
863
+ }
864
+ #endif
865
+
866
+ err = vkctx.gpu.createDevice(&deviceInfo, NULL, &vkctx.device);
867
+ if (err != vk::Result::eSuccess) {
868
+ assert(err != vk::Result::eErrorExtensionNotPresent);
869
+
870
+ std::string title;
871
+ std::stringstream msg;
872
+ title = szName;
873
+ title += ": vkCreateDevice Failure";
874
+ msg << "vkCreateDevice: unexpected failure: ";
875
+ msg << to_string(err) << ".";
876
+ (void)SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, title.c_str(),
877
+ msg.str().c_str(), NULL);
878
+ return false;
879
+ }
880
+
881
+ const vk::CommandPoolCreateInfo cmdPoolInfo(
882
+ vk::CommandPoolCreateFlagBits::eResetCommandBuffer,
883
+ vkctx.swapchain.queueIndex
884
+ );
885
+ err = vkctx.device.createCommandPool(&cmdPoolInfo,
886
+ nullptr, &vkctx.commandPool);
887
+ assert(err == vk::Result::eSuccess);
888
+
889
+ vkctx.device.getQueue(vkctx.swapchain.queueIndex, 0, &vkctx.queue);
890
+
891
+ return true;
892
+ } // createDevice
893
+
894
+
895
+ // Create synchronization objects
896
+ bool
897
+ VulkanAppSDL::createSemaphores()
898
+ {
899
+ VkSemaphoreCreateInfo semaphoreCreateInfo = {};
900
+ semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
901
+ semaphoreCreateInfo.pNext = NULL;
902
+ semaphoreCreateInfo.flags = 0;
903
+
904
+ // Semaphore used to synchronize image presentation.
905
+ // Ensures that the image is displayed before we start submitting new
906
+ // commands to the queue.
907
+ VK_CHECK_RESULT(vkCreateSemaphore(vkctx.device,
908
+ &semaphoreCreateInfo,
909
+ nullptr,
910
+ &semaphores.presentComplete));
911
+ // Semaphore used to synchronize render command submission.
912
+ // Ensures that the image is not presented until all render commands have
913
+ // been submitted and executed.
914
+ VK_CHECK_RESULT(vkCreateSemaphore(vkctx.device,
915
+ &semaphoreCreateInfo,
916
+ nullptr,
917
+ &semaphores.renderComplete));
918
+ // Semaphore used to synchronize text overlay command submission.
919
+ // Ensures that the image is not presented until all commands for the
920
+ // text overlay have been submitted and executed. Will be inserted after
921
+ // the render complete semaphore if the text overlay is enabled.
922
+ VK_CHECK_RESULT(vkCreateSemaphore(vkctx.device,
923
+ &semaphoreCreateInfo,
924
+ nullptr,
925
+ &semaphores.textOverlayComplete));
926
+
927
+ // Set up submit info structure
928
+ // Semaphores will stay the same during application lifetime
929
+ // Command buffer submission info is set by each example
930
+ vkctx.drawCmdSubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
931
+ vkctx.drawCmdSubmitInfo.pNext = NULL;
932
+ vkctx.drawCmdSubmitInfo.pWaitDstStageMask = &vkctx.submitPipelineStages;
933
+ vkctx.drawCmdSubmitInfo.waitSemaphoreCount = 1;
934
+ vkctx.drawCmdSubmitInfo.pWaitSemaphores = &semaphores.presentComplete;
935
+ vkctx.drawCmdSubmitInfo.signalSemaphoreCount = 1;
936
+ vkctx.drawCmdSubmitInfo.pSignalSemaphores = &semaphores.renderComplete;
937
+ return true;
938
+ }
939
+
940
+
941
+ bool
942
+ VulkanAppSDL::createSwapchain()
943
+ {
944
+ vkctx.swapchain.create(&w_width, &w_height, enableVSync);
945
+ return true;
946
+ } // createSwapchain
947
+
948
+
949
+ bool
950
+ VulkanAppSDL::prepareDepthBuffer()
951
+ {
952
+ vk::Format depthFormat;
953
+ vk::ImageAspectFlags aspectMask;
954
+
955
+ if (!getSupportedDepthFormat(vkctx.gpu, eNoStencil, e24bits,
956
+ vk::ImageTiling::eOptimal,
957
+ depthFormat, aspectMask))
958
+ return false;
959
+ vkctx.depthBuffer.format = static_cast<VkFormat>(depthFormat);
960
+
961
+ VkImageCreateInfo image = {};
962
+ image.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
963
+ image.pNext = NULL;
964
+ image.imageType = VK_IMAGE_TYPE_2D;
965
+ image.format = static_cast<VkFormat>(depthFormat);
966
+ image.extent.width = w_width;
967
+ image.extent.height = w_height;
968
+ image.extent.depth = 1;
969
+ image.mipLevels = 1;
970
+ image.arrayLayers = 1;
971
+ image.samples = VK_SAMPLE_COUNT_1_BIT;
972
+ image.tiling = VK_IMAGE_TILING_OPTIMAL;
973
+ image.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
974
+ | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
975
+ image.flags = 0;
976
+
977
+ VkImageViewCreateInfo view = { };
978
+ view.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
979
+ view.pNext = NULL;
980
+ view.image = VK_NULL_HANDLE;
981
+ view.format = static_cast<VkFormat>(depthFormat);
982
+ // Set just DEPTH_BIT as we're not using stencil. This is okay even if a
983
+ // packed depth-stencil format was selected by getSupportedDepthFormat.
984
+ view.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
985
+ view.subresourceRange.baseMipLevel = 0;
986
+ view.subresourceRange.levelCount = 1;
987
+ view.subresourceRange.baseArrayLayer = 0;
988
+ view.subresourceRange.layerCount = 1;
989
+ view.flags = 0;
990
+ view.viewType = VK_IMAGE_VIEW_TYPE_2D;
991
+
992
+ VkMemoryRequirements mem_reqs;
993
+ U_ASSERT_ONLY VkResult err;
994
+ U_ASSERT_ONLY bool pass;
995
+
996
+ /* create image */
997
+ err = vkCreateImage(vkctx.device, &image, NULL, &vkctx.depthBuffer.image);
998
+ assert(!err);
999
+
1000
+ vkGetImageMemoryRequirements(vkctx.device, vkctx.depthBuffer.image,
1001
+ &mem_reqs);
1002
+
1003
+ vkctx.depthBuffer.memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
1004
+ vkctx.depthBuffer.memAlloc.pNext = NULL;
1005
+ vkctx.depthBuffer.memAlloc.allocationSize = mem_reqs.size;
1006
+ vkctx.depthBuffer.memAlloc.memoryTypeIndex = 0;
1007
+
1008
+ pass = vkctx.getMemoryType(mem_reqs.memoryTypeBits,
1009
+ vk::MemoryPropertyFlagBits::eDeviceLocal,
1010
+ &vkctx.depthBuffer.memAlloc.memoryTypeIndex);
1011
+ assert(pass);
1012
+
1013
+ /* allocate memory */
1014
+ err = vkAllocateMemory(vkctx.device, &vkctx.depthBuffer.memAlloc, NULL,
1015
+ &vkctx.depthBuffer.mem);
1016
+ assert(!err);
1017
+
1018
+ /* bind memory */
1019
+ err =
1020
+ vkBindImageMemory(vkctx.device, vkctx.depthBuffer.image,
1021
+ vkctx.depthBuffer.mem, 0);
1022
+ assert(!err);
1023
+
1024
+ setImageLayout(vkctx.depthBuffer.image,
1025
+ static_cast<VkImageAspectFlags>(aspectMask),
1026
+ VK_IMAGE_LAYOUT_UNDEFINED,
1027
+ VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
1028
+ (VkAccessFlags)0);
1029
+
1030
+ /* create image view */
1031
+ view.image = vkctx.depthBuffer.image;
1032
+ err = vkCreateImageView(vkctx.device, &view, NULL, &vkctx.depthBuffer.view);
1033
+ assert(!err);
1034
+
1035
+ return true;
1036
+ } // prepareDepthBuffer
1037
+
1038
+
1039
+ bool
1040
+ VulkanAppSDL::preparePresentCommandBuffers()
1041
+ {
1042
+ VkCommandBufferBeginInfo cmdBufferBeginInfo = {};
1043
+ cmdBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
1044
+ cmdBufferBeginInfo.pNext = NULL;
1045
+
1046
+ for (uint32_t i = 0; i < vkctx.swapchain.imageCount; i++)
1047
+ {
1048
+ // Command buffer for post present barrier
1049
+
1050
+ // Insert a post present image barrier to transform the image back to a
1051
+ // color attachment that our render pass can write to. We always use
1052
+ // undefined image layout as the source as it doesn't actually matter
1053
+ // what is done with the previous image contents
1054
+
1055
+ VK_CHECK_RESULT(vkBeginCommandBuffer(vkctx.postPresentCmdBuffers[i],
1056
+ &cmdBufferBeginInfo));
1057
+
1058
+ VkImageMemoryBarrier postPresentBarrier = { };
1059
+ postPresentBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
1060
+ postPresentBarrier.pNext = NULL;
1061
+ postPresentBarrier.srcAccessMask = 0;
1062
+ postPresentBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
1063
+ postPresentBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1064
+ postPresentBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1065
+ postPresentBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1066
+ postPresentBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1067
+ postPresentBarrier.subresourceRange =
1068
+ { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
1069
+ postPresentBarrier.image = vkctx.swapchain.buffers[i].image;
1070
+
1071
+ vkCmdPipelineBarrier(
1072
+ vkctx.postPresentCmdBuffers[i],
1073
+ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
1074
+ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
1075
+ 0,
1076
+ 0, nullptr,
1077
+ 0, nullptr,
1078
+ 1, &postPresentBarrier);
1079
+
1080
+ VK_CHECK_RESULT(vkEndCommandBuffer(vkctx.postPresentCmdBuffers[i]));
1081
+
1082
+ // Command buffer for pre present barrier
1083
+
1084
+ // Submit a pre present image barrier to the queue.
1085
+ // Transforms the (framebuffer) image layout from color attachment to
1086
+ // present(khr) for presenting to the swap chain.
1087
+
1088
+ VK_CHECK_RESULT(vkBeginCommandBuffer(vkctx.prePresentCmdBuffers[i],
1089
+ &cmdBufferBeginInfo));
1090
+
1091
+ VkImageMemoryBarrier prePresentBarrier = { };
1092
+ prePresentBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
1093
+ prePresentBarrier.pNext = NULL;
1094
+ prePresentBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
1095
+ prePresentBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
1096
+ prePresentBarrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1097
+ prePresentBarrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
1098
+ prePresentBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1099
+ prePresentBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1100
+ prePresentBarrier.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
1101
+ prePresentBarrier.image = vkctx.swapchain.buffers[i].image;
1102
+
1103
+ vkCmdPipelineBarrier(
1104
+ vkctx.prePresentCmdBuffers[i],
1105
+ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
1106
+ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
1107
+ 0,
1108
+ 0, nullptr, // No memory barriers,
1109
+ 0, nullptr, // No buffer barriers,
1110
+ 1, &prePresentBarrier);
1111
+
1112
+ VK_CHECK_RESULT(vkEndCommandBuffer(vkctx.prePresentCmdBuffers[i]));
1113
+ }
1114
+ return true;
1115
+ }
1116
+
1117
+
1118
+ bool
1119
+ VulkanAppSDL::prepareDescriptorLayout()
1120
+ {
1121
+ return true;
1122
+ }
1123
+
1124
+
1125
+ bool
1126
+ VulkanAppSDL::prepareRenderPass()
1127
+ {
1128
+ VkAttachmentDescription attachments[2] = { };
1129
+ attachments[0].format = vkctx.swapchain.colorFormat;
1130
+ attachments[0].samples = VK_SAMPLE_COUNT_1_BIT;
1131
+ attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1132
+ attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
1133
+ attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
1134
+ attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1135
+ attachments[0].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1136
+ attachments[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1137
+
1138
+ attachments[1].format = vkctx.depthBuffer.format;
1139
+ attachments[1].samples = VK_SAMPLE_COUNT_1_BIT;
1140
+ attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1141
+ attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1142
+ attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
1143
+ attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1144
+ attachments[1].initialLayout =
1145
+ VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
1146
+ attachments[1].finalLayout =
1147
+ VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
1148
+
1149
+ const VkAttachmentReference color_reference = {
1150
+ 0,
1151
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1152
+ };
1153
+ const VkAttachmentReference depth_reference = {
1154
+ 1,
1155
+ VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
1156
+ };
1157
+ const VkSubpassDescription subpass = {
1158
+ 0,
1159
+ VK_PIPELINE_BIND_POINT_GRAPHICS,
1160
+ 0,
1161
+ NULL,
1162
+ 1,
1163
+ &color_reference,
1164
+ NULL,
1165
+ &depth_reference,
1166
+ 0,
1167
+ NULL,
1168
+ };
1169
+ const VkRenderPassCreateInfo rp_info = {
1170
+ VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
1171
+ NULL,
1172
+ 0,
1173
+ 2,
1174
+ attachments,
1175
+ 1,
1176
+ &subpass,
1177
+ 0,
1178
+ NULL,
1179
+ };
1180
+ U_ASSERT_ONLY VkResult err;
1181
+
1182
+ err = vkCreateRenderPass(vkctx.device, &rp_info, NULL, &vkctx.renderPass);
1183
+ assert(!err);
1184
+ return true;
1185
+ }
1186
+
1187
+
1188
+ bool
1189
+ VulkanAppSDL::createPipelineCache()
1190
+ {
1191
+ VkPipelineCacheCreateInfo pipelineCacheCreateInfo = {};
1192
+ pipelineCacheCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
1193
+ VK_CHECK_RESULT(vkCreatePipelineCache(vkctx.device,
1194
+ &pipelineCacheCreateInfo,
1195
+ nullptr, &vkctx.pipelineCache));
1196
+ return true;
1197
+ }
1198
+
1199
+
1200
+ bool
1201
+ VulkanAppSDL::preparePipeline()
1202
+ {
1203
+ return true;
1204
+ }
1205
+
1206
+
1207
+ bool
1208
+ VulkanAppSDL::prepareDescriptorSet()
1209
+ {
1210
+ return true;
1211
+ }
1212
+
1213
+
1214
+ bool
1215
+ VulkanAppSDL::prepareFramebuffers()
1216
+ {
1217
+ VkImageView attachments[2];
1218
+ attachments[1] = vkctx.depthBuffer.view;
1219
+
1220
+ const VkFramebufferCreateInfo fb_info = {
1221
+ VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
1222
+ NULL,
1223
+ 0,
1224
+ vkctx.renderPass,
1225
+ 2,
1226
+ attachments,
1227
+ w_width,
1228
+ w_height,
1229
+ 1,
1230
+ };
1231
+ U_ASSERT_ONLY VkResult err;
1232
+ uint32_t i;
1233
+
1234
+ vkctx.framebuffers.resize(vkctx.swapchain.imageCount);
1235
+ for (i = 0; i < vkctx.framebuffers.size(); i++) {
1236
+ attachments[0] = vkctx.swapchain.buffers[i].view;
1237
+ err = vkCreateFramebuffer(vkctx.device, &fb_info, NULL,
1238
+ &vkctx.framebuffers[i]);
1239
+ assert(!err);
1240
+ }
1241
+ return true;
1242
+ }
1243
+
1244
+
1245
+ void
1246
+ VulkanAppSDL::flushInitialCommands()
1247
+ {
1248
+ U_ASSERT_ONLY VkResult err;
1249
+
1250
+ if (setupCmdBuffer == VK_NULL_HANDLE)
1251
+ return;
1252
+
1253
+ err = vkEndCommandBuffer(setupCmdBuffer);
1254
+ assert(!err);
1255
+
1256
+ const VkCommandBuffer cmd_bufs[] = { setupCmdBuffer };
1257
+ VkFence nullFence = VK_NULL_HANDLE;
1258
+ VkSubmitInfo sInfo;
1259
+ sInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1260
+ sInfo.pNext = NULL;
1261
+ sInfo.waitSemaphoreCount = 0;
1262
+ sInfo.pWaitSemaphores = NULL;
1263
+ sInfo.pWaitDstStageMask = NULL;
1264
+ sInfo.commandBufferCount = 1;
1265
+ sInfo.pCommandBuffers = cmd_bufs;
1266
+ sInfo.signalSemaphoreCount = 0;
1267
+ sInfo.pSignalSemaphores = NULL;
1268
+
1269
+ err = vkQueueSubmit(vkctx.queue, 1, &sInfo, nullFence);
1270
+ assert(!err);
1271
+
1272
+ err = vkQueueWaitIdle(vkctx.queue);
1273
+ assert(!err);
1274
+
1275
+ vkFreeCommandBuffers(vkctx.device, vkctx.commandPool, 1, cmd_bufs);
1276
+ setupCmdBuffer = VK_NULL_HANDLE;
1277
+
1278
+ }
1279
+
1280
+
1281
+ //----------------------------------------------------------------------
1282
+ // Window title and text overlay functions
1283
+ //----------------------------------------------------------------------
1284
+
1285
+
1286
+ void
1287
+ VulkanAppSDL::setWindowTitle()
1288
+ {
1289
+ if (!enableTextOverlay) {
1290
+ std::stringstream ss;
1291
+ std::string wt;
1292
+
1293
+ ss << std::fixed << std::setprecision(2)
1294
+ << lastFrameTime << "ms (" << fpsCounter.lastFPS << " fps)" << " ";
1295
+ wt = ss.str();
1296
+ wt += appTitle;
1297
+ SDL_SetWindowTitle(pswMainWindow, wt.c_str());
1298
+ } else {
1299
+ SDL_SetWindowTitle(pswMainWindow, appTitle.c_str());
1300
+ }
1301
+ }
1302
+
1303
+
1304
+ void
1305
+ VulkanAppSDL::prepareTextOverlay()
1306
+ {
1307
+ if (enableTextOverlay) {
1308
+ // Load the text rendering shaders
1309
+ std::vector<VkPipelineShaderStageCreateInfo> shaderStages;
1310
+ VkPipelineShaderStageCreateInfo shaderStage;
1311
+ std::string filepath = getAssetPath() + "textoverlay.vert.spv";
1312
+ shaderStage = static_cast<VkPipelineShaderStageCreateInfo>(vkctx.loadShader(filepath, vk::ShaderStageFlagBits::eVertex));
1313
+ shaderStages.push_back(shaderStage);
1314
+ shaderModules.push_back(shaderStage.module);
1315
+ filepath = getAssetPath() + "textoverlay.frag.spv";
1316
+ shaderStage = static_cast<VkPipelineShaderStageCreateInfo>(vkctx.loadShader(filepath, vk::ShaderStageFlagBits::eFragment));
1317
+ shaderStages.push_back(shaderStage);
1318
+ shaderModules.push_back(shaderStage.module);
1319
+
1320
+ textOverlay = new VulkanTextOverlay(
1321
+ vkctx.gpu,
1322
+ vkctx.device,
1323
+ vkctx.queue,
1324
+ vkctx.framebuffers,
1325
+ vkctx.swapchain.colorFormat,
1326
+ vkctx.depthBuffer.format,
1327
+ &w_width,
1328
+ &w_height,
1329
+ shaderStages
1330
+ );
1331
+ updateTextOverlay();
1332
+ }
1333
+ }
1334
+
1335
+
1336
+ void VulkanAppSDL::updateTextOverlay()
1337
+ {
1338
+ if (!enableTextOverlay)
1339
+ return;
1340
+
1341
+ textOverlay->beginTextUpdate();
1342
+
1343
+ textOverlay->addText(appTitle, 5.0f, 5.0f, VulkanTextOverlay::alignLeft);
1344
+
1345
+ std::stringstream ss;
1346
+ ss << std::fixed << std::setprecision(2)
1347
+ << lastFrameTime << "ms (" << fpsCounter.lastFPS << " fps)";
1348
+ textOverlay->addText(ss.str(), 5.0f, 25.0f, VulkanTextOverlay::alignLeft);
1349
+
1350
+ // Cast is a workaround for a change in Vulkan SDK 1.2.141 to the
1351
+ // declaration of deviceName in PhysicalDeviceProperties from a char
1352
+ // array to use an Array1D template.
1353
+ textOverlay->addText((char*)vkctx.gpuProperties.deviceName, 5.0f, 45.0f,
1354
+ VulkanTextOverlay::alignLeft);
1355
+
1356
+ // Leave a blank line between us and the derived class's text.
1357
+ getOverlayText(85.0f);
1358
+
1359
+ textOverlay->endTextUpdate();
1360
+ }
1361
+
1362
+
1363
+ void VulkanAppSDL::getOverlayText(float /*yOffset*/)
1364
+ {
1365
+ // Can be overriden in derived class
1366
+ }
1367
+
1368
+
1369
+ //----------------------------------------------------------------------
1370
+ // Utility functions
1371
+ //----------------------------------------------------------------------
1372
+
1373
+ // @brief Find suitable depth format to use.
1374
+ //
1375
+ // All depth formats are optional. This finds a supported format with at
1376
+ // least the required number of bits and without stencil, if possible and
1377
+ // not required.
1378
+ bool
1379
+ VulkanAppSDL::getSupportedDepthFormat(vk::PhysicalDevice gpu,
1380
+ stencilRequirement requiredStencil,
1381
+ depthRequirement requiredDepth,
1382
+ vk::ImageTiling tiling,
1383
+ vk::Format& depthFormat,
1384
+ vk::ImageAspectFlags& aspectMask)
1385
+ {
1386
+ struct depthFormatDescriptor {
1387
+ stencilRequirement stencil;
1388
+ depthRequirement depth;
1389
+ vk::Format vkformat;
1390
+ };
1391
+ std::vector<depthFormatDescriptor> depthFormats = {
1392
+ { eNoStencil, e16bits, vk::Format::eD16Unorm },
1393
+ { eStencil, e16bits, vk::Format::eD16UnormS8Uint },
1394
+ { eStencil, e24bits, vk::Format::eD24UnormS8Uint },
1395
+ { eNoStencil, e32bits, vk::Format::eD32Sfloat },
1396
+ { eStencil, e32bits, vk::Format::eD32SfloatS8Uint }
1397
+ };
1398
+
1399
+ for (auto& format : depthFormats)
1400
+ {
1401
+ if (format.depth >= requiredDepth
1402
+ && format.stencil >= requiredStencil) {
1403
+ vk::FormatProperties formatProps;
1404
+ gpu.getFormatProperties(format.vkformat, &formatProps);
1405
+ // Format must support depth stencil attachment for tiling
1406
+ vk::FormatFeatureFlags features;
1407
+ if (tiling == vk::ImageTiling::eOptimal)
1408
+ features = formatProps.optimalTilingFeatures;
1409
+ else
1410
+ features = formatProps.linearTilingFeatures;
1411
+ if (features & vk::FormatFeatureFlagBits::eDepthStencilAttachment) {
1412
+ depthFormat = format.vkformat;
1413
+ if (format.stencil == eStencil)
1414
+ aspectMask = vk::ImageAspectFlagBits::eDepth | vk::ImageAspectFlagBits::eStencil;
1415
+ else
1416
+ aspectMask = vk::ImageAspectFlagBits::eDepth;
1417
+ return true;
1418
+ }
1419
+ }
1420
+ }
1421
+ (void)SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, szName,
1422
+ "The VkPhysicalDevice does not support a suitable depth buffer.",
1423
+ NULL);
1424
+ return false;
1425
+ }
1426
+
1427
+ void
1428
+ VulkanAppSDL::setImageLayout(VkImage image, VkImageAspectFlags aspectMask,
1429
+ VkImageLayout old_image_layout,
1430
+ VkImageLayout new_image_layout,
1431
+ VkImageAspectFlags srcAccessMask)
1432
+ {
1433
+ U_ASSERT_ONLY VkResult err;
1434
+
1435
+ if (setupCmdBuffer == VK_NULL_HANDLE) {
1436
+ const VkCommandBufferAllocateInfo cbaInfo = {
1437
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
1438
+ NULL,
1439
+ vkctx.commandPool,
1440
+ VK_COMMAND_BUFFER_LEVEL_PRIMARY,
1441
+ 1,
1442
+ };
1443
+
1444
+ err = vkAllocateCommandBuffers(vkctx.device, &cbaInfo,
1445
+ &setupCmdBuffer);
1446
+ assert(!err);
1447
+
1448
+ VkCommandBufferInheritanceInfo cmdBufHInfo = { };
1449
+ cmdBufHInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
1450
+ cmdBufHInfo.pNext = NULL;
1451
+ cmdBufHInfo.renderPass = VK_NULL_HANDLE;
1452
+ cmdBufHInfo.subpass = 0;
1453
+ cmdBufHInfo.framebuffer = VK_NULL_HANDLE;
1454
+ cmdBufHInfo.occlusionQueryEnable = VK_FALSE;
1455
+ cmdBufHInfo.queryFlags = 0;
1456
+ cmdBufHInfo.pipelineStatistics = 0;
1457
+
1458
+ VkCommandBufferBeginInfo cmdBufInfo = { };
1459
+ cmdBufInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
1460
+ cmdBufInfo.pNext = NULL;
1461
+ cmdBufInfo.flags = 0;
1462
+ cmdBufInfo.pInheritanceInfo = &cmdBufHInfo;
1463
+
1464
+ err = vkBeginCommandBuffer(setupCmdBuffer, &cmdBufInfo);
1465
+ assert(!err);
1466
+ }
1467
+
1468
+ VkImageMemoryBarrier imageMemoryBarrier = { };
1469
+ imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
1470
+ imageMemoryBarrier.pNext = NULL;
1471
+ imageMemoryBarrier.srcAccessMask = srcAccessMask;
1472
+ imageMemoryBarrier.dstAccessMask = 0;
1473
+ imageMemoryBarrier.oldLayout = old_image_layout;
1474
+ imageMemoryBarrier.newLayout = new_image_layout;
1475
+ imageMemoryBarrier.image = image;
1476
+ imageMemoryBarrier.subresourceRange.aspectMask = aspectMask;
1477
+ imageMemoryBarrier.subresourceRange.baseMipLevel = 0;
1478
+ imageMemoryBarrier.subresourceRange.levelCount = 1;
1479
+ imageMemoryBarrier.subresourceRange.baseArrayLayer = 0;
1480
+ imageMemoryBarrier.subresourceRange.layerCount = 1;
1481
+
1482
+ if (new_image_layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
1483
+ /* Make sure anything that was copying from this image has completed */
1484
+ imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
1485
+ }
1486
+
1487
+ if (new_image_layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
1488
+ imageMemoryBarrier.dstAccessMask =
1489
+ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
1490
+ }
1491
+
1492
+ if (new_image_layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
1493
+ imageMemoryBarrier.dstAccessMask =
1494
+ VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
1495
+ }
1496
+
1497
+ if (new_image_layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
1498
+ /* Make sure any Copy or CPU writes to image are flushed */
1499
+ imageMemoryBarrier.dstAccessMask =
1500
+ VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
1501
+ }
1502
+
1503
+ VkPipelineStageFlags src_stages = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
1504
+ VkPipelineStageFlags dest_stages = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
1505
+
1506
+ vkCmdPipelineBarrier(setupCmdBuffer, src_stages, dest_stages, 0, 0,
1507
+ NULL, 0, NULL, 1, &imageMemoryBarrier);
1508
+ } // setImageLayout
1509
+
1510
+
1511
+ /*
1512
+ * @internal
1513
+ * @~English
1514
+ * @brief Check if all layer names specified in @p names can be
1515
+ * found in the given layer properties.
1516
+ *
1517
+ * @return true if all layer names can be found, false otherwise.
1518
+ */
1519
+ bool
1520
+ VulkanAppSDL::checkLayers(uint32_t nameCount, const char **names,
1521
+ uint32_t layerCount,
1522
+ VkLayerProperties *layers)
1523
+ {
1524
+ for (uint32_t i = 0; i < nameCount; i++) {
1525
+ bool found = 0;
1526
+ for (uint32_t j = 0; j < layerCount; j++) {
1527
+ if (!strcmp(names[i], layers[j].layerName)) {
1528
+ found = 1;
1529
+ break;
1530
+ }
1531
+ }
1532
+ if (!found) {
1533
+ fprintf(stderr, "Cannot find layer: %s\n", names[i]);
1534
+ return 0;
1535
+ }
1536
+ }
1537
+ return 1;
1538
+ }
1539
+
1540
+
1541
+ VKAPI_ATTR VkBool32 VKAPI_CALL
1542
+ VulkanAppSDL::debugFunc(VkDebugReportFlagsEXT msgFlags,
1543
+ VkDebugReportObjectTypeEXT objType,
1544
+ uint64_t srcObject, size_t location, int32_t msgCode,
1545
+ const char *pLayerPrefix, const char *pMsg,
1546
+ void *pUserData)
1547
+ {
1548
+ VulkanAppSDL* app = (VulkanAppSDL*)pUserData;
1549
+ return app->debugFunc(msgFlags, objType, srcObject, location, msgCode,
1550
+ pLayerPrefix, pMsg);
1551
+ }
1552
+
1553
+
1554
+ VKAPI_ATTR VkBool32 VKAPI_CALL
1555
+ VulkanAppSDL::debugFunc(VkDebugReportFlagsEXT msgFlags,
1556
+ VkDebugReportObjectTypeEXT /*objType*/,
1557
+ uint64_t /*srcObject*/, size_t /*location*/, int32_t msgCode,
1558
+ const char *pLayerPrefix, const char *pMsg)
1559
+ {
1560
+
1561
+ std::string title = szName;
1562
+ std::string text(pMsg);
1563
+ std::string prefix("");
1564
+ std::stringstream message;
1565
+ uint32_t mbFlags = SDL_MESSAGEBOX_INFORMATION;
1566
+
1567
+ // Errors may cause undefined behaviour or a crash.
1568
+ if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
1569
+ mbFlags = SDL_MESSAGEBOX_ERROR;
1570
+ prefix += "ERROR:";
1571
+ }
1572
+ // Warnings indicate use of Vulkan that may expose an app bug
1573
+ if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
1574
+ // We know that we're submitting queues without fences, ignore this
1575
+ // warning
1576
+ // XXX Check this
1577
+ if (strstr(pMsg,
1578
+ "vkQueueSubmit parameter, VkFence fence, is null pointer")) {
1579
+ return false;
1580
+ }
1581
+ mbFlags = SDL_MESSAGEBOX_WARNING;
1582
+ prefix += "WARNING:";
1583
+ }
1584
+ // Performance warnings indicate sub-optimal usage of the API
1585
+ if (msgFlags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT)
1586
+ {
1587
+ mbFlags = SDL_MESSAGEBOX_WARNING;
1588
+ prefix += "PERFORMANCE:";
1589
+ };
1590
+ // Information that may be handy during debugging.
1591
+ if (msgFlags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT)
1592
+ {
1593
+ mbFlags = SDL_MESSAGEBOX_INFORMATION;
1594
+ prefix += "INFO:";
1595
+ }
1596
+ // Diagnostic info from the Vulkan loader and layers.
1597
+ #if 0
1598
+ // Usually not helpful in terms of API usage, but may help to debug layer
1599
+ // and loader problems
1600
+ if (msgFlags & VK_DEBUG_REPORT_DEBUG_BIT_EXT)
1601
+ {
1602
+ mbFlags = SDL_MESSAGEBOX_INFORMATION;
1603
+ prefix += "DEBUG:";
1604
+ }
1605
+ #endif
1606
+ message << prefix << " [" << pLayerPrefix << "] Code "
1607
+ << std::showbase << std::internal << std::setfill('0') << std::hex
1608
+ << std::setw(8) << msgCode << ": " << std::endl << text;
1609
+
1610
+ title += " Debug Report";
1611
+ if (showDebugReport(mbFlags, title, message.str(), prepared)) {
1612
+ SDL_Event sdlevent;
1613
+ sdlevent.type = SDL_EVENT_QUIT;
1614
+ sdlevent.quit.timestamp = SDL_GetTicks();
1615
+
1616
+ (void)SDL_PushEvent(&sdlevent);
1617
+ }
1618
+
1619
+ /*
1620
+ * false indicates that layer should not bail-out of an
1621
+ * API call that had validation failures. This may mean that the
1622
+ * app dies inside the driver due to invalid parameter(s).
1623
+ * That's what would happen without validation layers, so we'll
1624
+ * keep that behavior here.
1625
+ */
1626
+ return false;
1627
+ }
1628
+
1629
+
1630
+ std::string&
1631
+ VulkanAppSDL::wrapText(std::string& source, size_t width,
1632
+ const std::string& whitespace)
1633
+ {
1634
+ if (source.length() <= width)
1635
+ return source;
1636
+
1637
+ // Find the longest "word" and possibly set @a width to that. The
1638
+ // message box width is set from the longest line and many of
1639
+ // the debug messages contain a long URL reference which could
1640
+ // easily be wider than @a width.
1641
+ size_t ws = source.find_first_not_of(whitespace);
1642
+ size_t we = 0;
1643
+ size_t maxWordLength = 0;
1644
+ for (; ws < source.length(); ws = we + 1) {
1645
+ size_t wl;
1646
+ we = source.find_first_of(whitespace, ws);
1647
+ if (we == std::string::npos) we = source.length();
1648
+ wl = we - ws;
1649
+ if (wl > maxWordLength) maxWordLength = wl;
1650
+ }
1651
+ if (maxWordLength > width)
1652
+ width = maxWordLength;
1653
+
1654
+ // If the string is one long word, nothing further to do.
1655
+ if (source.length() == width)
1656
+ return source;
1657
+
1658
+ size_t endPos = width, startPos = 0;
1659
+ while (startPos < source.length())
1660
+ {
1661
+ size_t breakPos, sizeToElim;
1662
+
1663
+ endPos = source.find_last_of(whitespace, endPos);
1664
+ if (endPos == std::string::npos)
1665
+ break;
1666
+ if (endPos > startPos) {
1667
+ breakPos = source.find_last_not_of(whitespace, endPos) + 1;
1668
+ if (breakPos == std::string::npos)
1669
+ break;
1670
+ endPos = source.find_first_not_of(whitespace, ++endPos);
1671
+ sizeToElim = endPos - breakPos;
1672
+ source.replace( breakPos, sizeToElim , "\n");
1673
+ startPos = endPos;
1674
+ } else { // have to tolerate a long line
1675
+ startPos += width;
1676
+ }
1677
+ endPos += width;
1678
+ }
1679
+ return source;
1680
+ }
1681
+
1682
+
1683
+ uint32_t
1684
+ VulkanAppSDL::showDebugReport(uint32_t mbFlags, const std::string title,
1685
+ std::string message, bool enableAbort)
1686
+ {
1687
+ const SDL_MessageBoxButtonData buttons[] = {
1688
+ /* .flags, .buttonid, .text */
1689
+ { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 0, "Continue" },
1690
+ { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 1, "Abort" },
1691
+ };
1692
+ #if 0
1693
+ const SDL_MessageBoxColorScheme colorScheme = {
1694
+ { /* .colors (.r, .g, .b) */
1695
+ /* [SDL_MESSAGEBOX_COLOR_BACKGROUND] */
1696
+ { 255, 0, 0 },
1697
+ /* [SDL_MESSAGEBOX_COLOR_TEXT] */
1698
+ { 0, 255, 0 },
1699
+ /* [SDL_MESSAGEBOX_COLOR_BUTTON_BORDER] */
1700
+ { 255, 255, 0 },
1701
+ /* [SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND] */
1702
+ { 0, 0, 255 },
1703
+ /* [SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED] */
1704
+ { 255, 0, 255 }
1705
+ }
1706
+ };
1707
+ #endif
1708
+ wrapText(message, 70, " \t\r");
1709
+ const SDL_MessageBoxData messageboxdata = {
1710
+ mbFlags, // .flags
1711
+ NULL, // .window
1712
+ title.c_str(), // .title
1713
+ message.c_str(), // .message
1714
+ (int)(enableAbort ? SDL_arraysize(buttons) : 1), // .numbuttons
1715
+ buttons, // .buttons
1716
+ NULL //&colorScheme // .colorScheme
1717
+ };
1718
+ int buttonid;
1719
+ if (!SDL_ShowMessageBox(&messageboxdata, &buttonid)) {
1720
+ SDL_Log("error displaying message box");
1721
+ }
1722
+ if (buttonid == -1) {
1723
+ SDL_Log("no selection");
1724
+ return 0;
1725
+ } else {
1726
+ return buttonid;
1727
+ }
1728
+ }
1729
+
1730
+ #if SDL_PLATFORM_WINDOWS
1731
+ // Windows specific code to use icon in module
1732
+ #define WIN32_LEAN_AND_MEAN
1733
+ #include <Windows.h>
1734
+ void setWindowsIcon(SDL_Window *sdlWindow) {
1735
+ HINSTANCE handle = ::GetModuleHandle(nullptr);
1736
+ // Identify icon by name rather than IDI_ macro to avoid having to
1737
+ // include application's resource.h.
1738
+ HICON icon = ::LoadIcon(handle, "MAIN_ICON"); // MAKEINTRESOURCE(IDI_ICON1));
1739
+ if (icon != nullptr) {
1740
+ HWND hwnd = (HWND)SDL_GetPointerProperty(SDL_GetWindowProperties(sdlWindow),
1741
+ SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL);
1742
+ if (hwnd) {
1743
+ ::SetClassLongPtr(hwnd, GCLP_HICON, reinterpret_cast<LONG_PTR>(icon));
1744
+ }
1745
+ }
1746
+ }
1747
+ #endif
1748
+
third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/VulkanAppSDL.h ADDED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* -*- tab-width: 4; -*- */
2
+ /* vi: set sw=2 ts=4 expandtab: */
3
+
4
+ #ifndef VULKAN_APP_SDL_H_1456211188
5
+ #define VULKAN_APP_SDL_H_1456211188
6
+
7
+ /*
8
+ * Copyright 2017-2020 Mark Callow.
9
+ * SPDX-License-Identifier: Apache-2.0
10
+ */
11
+
12
+ #include <array>
13
+ #include <cstring>
14
+ #include <new>
15
+ #include <vector>
16
+ #define VK_ENABLE_BETA_EXTENSIONS 1
17
+ #include <vulkan/vulkan.hpp>
18
+ #include <SDL3/SDL_vulkan.h> // Must be after vulkan.hpp.
19
+
20
+ #include "AppBaseSDL.h"
21
+ #include "VulkanContext.h"
22
+ #include "VulkanSwapchain.h"
23
+ #include "vulkantextoverlay.hpp"
24
+ #include "unused.h"
25
+
26
+ class VulkanAppSDL : public AppBaseSDL {
27
+ public:
28
+ VulkanAppSDL(const char* const name,
29
+ int width, int height,
30
+ const uint32_t version,
31
+ bool enableTextOverlay)
32
+ : AppBaseSDL(name), w_width(width), w_height(height),
33
+ subOptimalPresentWarned(false), validate(false),
34
+ vkVersion(version),
35
+ enableTextOverlay(enableTextOverlay),
36
+ textOverlay(nullptr)
37
+ {
38
+ // The overridden new below will zero the storage. Thus
39
+ // we avoid a long list of initializers.
40
+ appTitle = name;
41
+ };
42
+ virtual ~VulkanAppSDL();
43
+ virtual bool doEvent(SDL_Event* event);
44
+ virtual void drawFrame(uint32_t msTicks);
45
+ virtual void finalize();
46
+ virtual bool initialize(Args& args);
47
+ virtual void onFPSUpdate();
48
+ virtual void resizeWindow(int width, int height);
49
+ virtual void windowResized();
50
+
51
+ static void* operator new(size_t size) {
52
+ void* storage = ::operator new(size);
53
+ memset(storage, 0, size);
54
+ return storage;
55
+ }
56
+
57
+ static void operator delete(void* storage, size_t) {
58
+ ::operator delete(storage);
59
+ }
60
+
61
+ void updateTextOverlay();
62
+
63
+ // Called when the text overlay is updating
64
+ // Can be overridden in derived class to add custom text to the overlay
65
+ virtual void getOverlayText(float yOffset);
66
+
67
+ protected:
68
+ bool createDevice();
69
+ bool createInstance();
70
+ bool createPipelineCache();
71
+ bool createSemaphores();
72
+ bool createSurface();
73
+ bool createSwapchain();
74
+ bool findGpu();
75
+ void flushInitialCommands();
76
+ bool initializeVulkan();
77
+ bool prepareColorBuffers();
78
+ bool prepareCommandBuffers();
79
+ bool prepareDepthBuffer();
80
+ bool prepareDescriptorLayout();
81
+ void prepareFrame();
82
+ bool preparePresentCommandBuffers();
83
+ bool prepareRenderPass();
84
+ bool preparePipeline();
85
+ bool prepareDescriptorSet();
86
+ bool prepareFramebuffers();
87
+ void prepareTextOverlay();
88
+ void submitFrame();
89
+
90
+ bool setupDebugReporting();
91
+
92
+ enum stencilRequirement { eNoStencil = 0, eStencil = 1 };
93
+ enum depthRequirement { e16bits = 0, e24bits = 1, e32bits = 2 };
94
+ bool getSupportedDepthFormat(vk::PhysicalDevice gpu,
95
+ stencilRequirement requiredStencil,
96
+ depthRequirement requiredDepth,
97
+ vk::ImageTiling tiling,
98
+ vk::Format& pFormat,
99
+ vk::ImageAspectFlags& pAspectMask);
100
+
101
+ // Sets text on window title bar.
102
+ void setWindowTitle();
103
+
104
+ void setImageLayout(VkImage image, VkImageAspectFlags aspectMask,
105
+ VkImageLayout old_image_layout,
106
+ VkImageLayout new_image_layout,
107
+ VkAccessFlags srcAccessMask);
108
+
109
+ VKAPI_ATTR VkBool32 VKAPI_CALL
110
+ debugFunc(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType,
111
+ uint64_t srcObject, size_t location, int32_t msgCode,
112
+ const char *pLayerPrefix, const char *pMsg);
113
+ std::string& wrapText(std::string& source, size_t width = 70,
114
+ const std::string& whitespace = " \t\r");
115
+ uint32_t showDebugReport(uint32_t mbFlags, const std::string title,
116
+ std::string message, bool enableAbort);
117
+
118
+ static bool checkLayers(uint32_t nameCount, const char **names,
119
+ uint32_t layerCount, VkLayerProperties *layers);
120
+ static VKAPI_ATTR VkBool32 VKAPI_CALL
121
+ debugFunc(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType,
122
+ uint64_t srcObject, size_t location, int32_t msgCode,
123
+ const char *pLayerPrefix, const char *pMsg, void *pUserData);
124
+
125
+ bool prepared = false;
126
+ // Set true if want presents v-sync'ed.
127
+ bool enableVSync = false;
128
+
129
+ uint32_t w_width;
130
+ uint32_t w_height;
131
+
132
+ bool subOptimalPresentWarned;
133
+ bool validate;
134
+
135
+ std::vector<const char*> extensionNames;
136
+ std::vector<const char*> deviceValidationLayers;
137
+
138
+ VkCommandBuffer setupCmdBuffer;
139
+ VkSurfaceKHR vsSurface;
140
+
141
+ VulkanContext vkctx;
142
+
143
+ // Index of active framebuffer.
144
+ uint32_t currentBuffer;
145
+
146
+ // Synchronization semaphores
147
+ struct {
148
+ // Swap chain image presentation
149
+ VkSemaphore presentComplete;
150
+ // Command buffer submission and execution
151
+ VkSemaphore renderComplete;
152
+ // Text overlay submission and execution
153
+ VkSemaphore textOverlayComplete;
154
+ } semaphores;
155
+
156
+ const uint32_t vkVersion;
157
+
158
+ // Saved for clean-up
159
+ std::vector<vk::ShaderModule> shaderModules;
160
+
161
+ bool enableTextOverlay = false;
162
+ VulkanTextOverlay *textOverlay;
163
+ // List of shader modules created (stored for cleanup)
164
+
165
+ VkDebugReportCallbackEXT msgCallback;
166
+
167
+ PFN_vkCreateDebugReportCallbackEXT pfnCreateDebugReportCallbackEXT;
168
+ PFN_vkDestroyDebugReportCallbackEXT pfnDestroyDebugReportCallbackEXT;
169
+ PFN_vkDebugReportMessageEXT pfnDebugReportMessageEXT;
170
+ };
171
+
172
+ #endif /* VULKAN_APP_SDL_H_1456211188 */
third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/VulkanContext.cpp ADDED
@@ -0,0 +1,363 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* -*- tab-width: 4; -*- */
2
+ /* vi: set sw=2 ts=4 expandtab: */
3
+
4
+ /*
5
+ * Copyright 2017-2020 Mark Callow.
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+
9
+
10
+ /**
11
+ * @internal
12
+ * @class VulkanContext
13
+ * @~English
14
+ *
15
+ * @brief Class for holding and passing Vulkan context info to applications.
16
+ *
17
+ * @author Mark Callow, github.com/MarkCallow.
18
+ */
19
+
20
+ #include <exception>
21
+ #include <iomanip>
22
+ #include <sstream>
23
+ #include <SDL3/SDL_iostream.h>
24
+ #include "VulkanContext.h"
25
+ // Until exceptions are used everywhere...
26
+ #include "vulkancheckres.h"
27
+ #include "ltexceptions.h"
28
+ #include "unused.h"
29
+
30
+ vk::CommandBuffer
31
+ VulkanContext::createCommandBuffer(vk::CommandBufferLevel level, bool begin)
32
+ {
33
+ vk::CommandBuffer cmdBuffer;
34
+
35
+ vk::CommandBufferAllocateInfo cmdBufAllocateInfo(
36
+ commandPool,
37
+ level,
38
+ 1);
39
+
40
+ vk::Result res
41
+ = device.allocateCommandBuffers(&cmdBufAllocateInfo, &cmdBuffer);
42
+
43
+ if (res != vk::Result::eSuccess) {
44
+ throw bad_vulkan_alloc((int)res, "device.allocateCommandBuffers");
45
+ }
46
+
47
+ // If requested, also start the new command buffer
48
+ if (begin)
49
+ {
50
+ vk::CommandBufferBeginInfo cmdBufInfo;
51
+ res = cmdBuffer.begin(&cmdBufInfo);
52
+ if (res != vk::Result::eSuccess) {
53
+ throw bad_vulkan_alloc((int)res, "cmdBuffer.begin");
54
+ }
55
+ }
56
+
57
+ return cmdBuffer;
58
+ }
59
+
60
+
61
+ void
62
+ VulkanContext::flushCommandBuffer(vk::CommandBuffer& cmdBuffer,
63
+ bool free)
64
+ {
65
+ if (!cmdBuffer) {
66
+ return;
67
+ }
68
+
69
+ cmdBuffer.end();
70
+
71
+ vk::SubmitInfo submitInfo;
72
+ submitInfo.commandBufferCount = 1;
73
+ submitInfo.pCommandBuffers = &cmdBuffer;
74
+
75
+ vk::Result res = queue.submit(1, &submitInfo, nullptr);
76
+ if (res != vk::Result::eSuccess) {
77
+ if (res == vk::Result::eErrorDeviceLost) {
78
+ throw std::runtime_error("Vulkan device lost.");
79
+ } else {
80
+ throw bad_vulkan_alloc((int)res, "queue.submit");
81
+ }
82
+ }
83
+
84
+ queue.waitIdle();
85
+
86
+ if (free) {
87
+ device.freeCommandBuffers(commandPool, 1, &cmdBuffer);
88
+ }
89
+ }
90
+
91
+ bool
92
+ VulkanContext::createDrawCommandBuffers()
93
+ {
94
+ VkCommandBufferAllocateInfo aInfo;
95
+ aInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
96
+ aInfo.pNext = NULL;
97
+ aInfo.commandPool = commandPool;
98
+ aInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
99
+ aInfo.commandBufferCount = 1;
100
+
101
+ drawCmdBuffers.resize(swapchain.imageCount);
102
+ for (uint32_t i = 0; i < swapchain.imageCount; i++) {
103
+ VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &aInfo,
104
+ &drawCmdBuffers[i]));
105
+ }
106
+ return true;
107
+ }
108
+
109
+ bool
110
+ VulkanContext::createPresentCommandBuffers()
111
+ {
112
+ VkCommandBufferAllocateInfo aInfo;
113
+ aInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
114
+ aInfo.pNext = NULL;
115
+ aInfo.commandPool = commandPool;
116
+ aInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
117
+ aInfo.commandBufferCount = 1;
118
+
119
+ prePresentCmdBuffers.resize(swapchain.imageCount);
120
+ postPresentCmdBuffers.resize(swapchain.imageCount);
121
+ for (uint32_t i = 0; i < swapchain.imageCount; i++) {
122
+ VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &aInfo,
123
+ &prePresentCmdBuffers[i]));
124
+ VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &aInfo,
125
+ &postPresentCmdBuffers[i]));
126
+ }
127
+ return true;
128
+ }
129
+
130
+ void
131
+ VulkanContext::destroyDrawCommandBuffers()
132
+ {
133
+ if (drawCmdBuffers.size() > 0) {
134
+ vkFreeCommandBuffers(device, commandPool,
135
+ static_cast<uint32_t>(drawCmdBuffers.size()),
136
+ drawCmdBuffers.data());
137
+ }
138
+ for (uint32_t i = 0; i < drawCmdBuffers.size(); ++i) {
139
+ drawCmdBuffers[i] = nullptr;
140
+ }
141
+
142
+ }
143
+
144
+ void
145
+ VulkanContext::destroyPresentCommandBuffers()
146
+ {
147
+ vkFreeCommandBuffers(device, commandPool,
148
+ static_cast<uint32_t>(drawCmdBuffers.size()),
149
+ prePresentCmdBuffers.data());
150
+ vkFreeCommandBuffers(device, commandPool,
151
+ static_cast<uint32_t>(drawCmdBuffers.size()),
152
+ postPresentCmdBuffers.data());
153
+ }
154
+
155
+ bool
156
+ VulkanContext::checkDrawCommandBuffers()
157
+ {
158
+ for (auto& cmdBuffer : drawCmdBuffers)
159
+ {
160
+ if (cmdBuffer == VK_NULL_HANDLE)
161
+ {
162
+ return false;
163
+ }
164
+ }
165
+ return true;
166
+ }
167
+
168
+ bool
169
+ VulkanContext::createBuffer(vk::BufferUsageFlags usageFlags,
170
+ vk::MemoryPropertyFlags memoryPropertyFlags,
171
+ vk::DeviceSize size,
172
+ void * data,
173
+ vk::Buffer* buffer,
174
+ vk::DeviceMemory* memory)
175
+ {
176
+ vk::MemoryRequirements memReqs;
177
+ vk::MemoryAllocateInfo memAlloc(0, 0);
178
+ vk::BufferCreateInfo bufferCreateInfo({}, size, usageFlags);
179
+
180
+ vk::Result res = device.createBuffer(&bufferCreateInfo, nullptr, buffer);
181
+ if (res != vk::Result::eSuccess) {
182
+ return false;
183
+ }
184
+
185
+ device.getBufferMemoryRequirements(*buffer, &memReqs);
186
+ memAlloc.allocationSize = memReqs.size;
187
+ memAlloc.memoryTypeIndex = getMemoryType(memReqs.memoryTypeBits,
188
+ memoryPropertyFlags);
189
+ res = device.allocateMemory(&memAlloc, nullptr, memory);
190
+ if (res == vk::Result::eSuccess) {
191
+ if (data != nullptr)
192
+ {
193
+ void *mapped;
194
+ mapped = device.mapMemory(*memory, 0, size, {});
195
+ memcpy(mapped, data, (size_t)size);
196
+ device.unmapMemory(*memory);
197
+ }
198
+ device.bindBufferMemory(*buffer, *memory, 0);
199
+
200
+ return true;
201
+ } else
202
+ return false;
203
+ }
204
+
205
+ bool
206
+ VulkanContext::createBuffer(vk::BufferUsageFlags usage,
207
+ vk::DeviceSize size,
208
+ void* data,
209
+ vk::Buffer* buffer,
210
+ vk::DeviceMemory* memory)
211
+ {
212
+ return createBuffer(usage, vk::MemoryPropertyFlagBits::eHostVisible,
213
+ size, data, buffer, memory);
214
+ }
215
+
216
+ bool
217
+ VulkanContext::createBuffer(vk::BufferUsageFlags usage,
218
+ vk::DeviceSize size,
219
+ void* data,
220
+ vk::Buffer* buffer,
221
+ vk::DeviceMemory* memory,
222
+ vk::DescriptorBufferInfo* descriptor)
223
+ {
224
+ bool res = createBuffer(usage, size, data, buffer, memory);
225
+ if (res)
226
+ {
227
+ descriptor->offset = 0;
228
+ descriptor->buffer = *buffer;
229
+ descriptor->range = size;
230
+ return true;
231
+ }
232
+ else
233
+ {
234
+ return false;
235
+ }
236
+ }
237
+
238
+ bool
239
+ VulkanContext::createBuffer(vk::BufferUsageFlags usage,
240
+ vk::MemoryPropertyFlags memoryPropertyFlags,
241
+ vk::DeviceSize size,
242
+ void* data,
243
+ vk::Buffer* buffer,
244
+ vk::DeviceMemory* memory,
245
+ vk::DescriptorBufferInfo* descriptor)
246
+ {
247
+ bool res = createBuffer(usage, memoryPropertyFlags, size, data, buffer, memory);
248
+ if (res)
249
+ {
250
+ descriptor->offset = 0;
251
+ descriptor->buffer = *buffer;
252
+ descriptor->range = size;
253
+ return true;
254
+ }
255
+ else
256
+ {
257
+ return false;
258
+ }
259
+ }
260
+
261
+ bool
262
+ VulkanContext::getMemoryType(uint32_t typeBits,
263
+ vk::MemoryPropertyFlags requirementsMask,
264
+ uint32_t *typeIndex) const
265
+ {
266
+ // Search memtypes to find first index with desired properties
267
+ for (uint32_t i = 0; i < VK_MAX_MEMORY_TYPES; i++) {
268
+ if ((typeBits & 1) == 1) {
269
+ // Type is available, does it match user properties?
270
+ if ((memoryProperties.memoryTypes[i].propertyFlags &
271
+ requirementsMask) == requirementsMask) {
272
+ *typeIndex = i;
273
+ return true;
274
+ }
275
+ }
276
+ typeBits >>= 1;
277
+ }
278
+ // No memory types matched, return failure
279
+ return false;
280
+ }
281
+
282
+ uint32_t
283
+ VulkanContext::getMemoryType(uint32_t typeBits,
284
+ vk::MemoryPropertyFlags requirementsMask) const
285
+ {
286
+ // Search memtypes to find first index with desired properties
287
+ for (uint32_t i = 0; i < VK_MAX_MEMORY_TYPES; i++) {
288
+ if ((typeBits & 1) == 1) {
289
+ // Type is available, does it match user properties?
290
+ if ((memoryProperties.memoryTypes[i].propertyFlags &
291
+ requirementsMask) == requirementsMask) {
292
+ return i;
293
+ }
294
+ }
295
+ typeBits >>= 1;
296
+ }
297
+ // No memory types matched, return failure
298
+ // TODO throw error
299
+ return 0;
300
+ }
301
+
302
+ vk::PipelineShaderStageCreateInfo
303
+ VulkanContext::loadShader(std::string filename,
304
+ vk::ShaderStageFlagBits stage,
305
+ const char* const modname)
306
+ {
307
+ vk::PipelineShaderStageCreateInfo shaderStage({}, stage);
308
+ shaderStage.module = loadShader(filename);
309
+ shaderStage.pName = modname;
310
+ return shaderStage;
311
+ }
312
+
313
+ vk::ShaderModule
314
+ VulkanContext::loadShader(std::string filename)
315
+ {
316
+ size_t codeSize;
317
+ uint32_t* shaderCode;
318
+
319
+ shaderCode = readSpv(filename.c_str(), &codeSize);
320
+
321
+ vk::ShaderModule shaderModule;
322
+ vk::ShaderModuleCreateInfo moduleCreateInfo({}, codeSize, shaderCode);
323
+
324
+ vk::Result res
325
+ = device.createShaderModule(&moduleCreateInfo, NULL, &shaderModule);
326
+ if (res != vk::Result::eSuccess) {
327
+ throw bad_vulkan_alloc((int)res, "device.createShaderModule");
328
+ }
329
+
330
+ delete[] shaderCode;
331
+
332
+ assert(shaderModule);
333
+ return shaderModule;
334
+ }
335
+
336
+ uint32_t*
337
+ VulkanContext::readSpv(const char *filename, size_t *pSize) {
338
+ size_t size;
339
+ U_ASSERT_ONLY size_t retval;
340
+ uint32_t* shader_code;
341
+
342
+ SDL_IOStream* io = SDL_IOFromFile(filename, "rb");
343
+ if (!io) {
344
+ std::stringstream message;
345
+
346
+ // String returned by SDL_GetError() includes file name.
347
+ message << "Open of shader failed: " << SDL_GetError();
348
+ throw std::runtime_error(message.str());
349
+ }
350
+
351
+ size = (size_t)SDL_GetIOSize(io);
352
+
353
+ // Round-up to next 4-byte size.
354
+ shader_code = new uint32_t[(size + 3)/4];
355
+ retval = SDL_ReadIO(io, shader_code, size);
356
+ assert(retval == size);
357
+
358
+ *pSize = size;
359
+
360
+ SDL_CloseIO(io);
361
+ return shader_code;
362
+ }
363
+
third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/VulkanContext.h ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* -*- tab-width: 4; -*- */
2
+ /* vi: set sw=2 ts=4 expandtab: */
3
+
4
+ #ifndef VULKAN_TEXTURE_H_229895365400979164311947449304284143508
5
+ #define VULKAN_TEXTURE_H_229895365400979164311947449304284143508
6
+
7
+ /*
8
+ * Copyright 2017-2020 Mark Callow.
9
+ * SPDX-License-Identifier: Apache-2.0
10
+ */
11
+
12
+ #include <vector>
13
+ #define VK_ENABLE_BETA_EXTENSIONS 1
14
+ #include <vulkan/vulkan.hpp>
15
+ #include "VulkanSwapchain.h"
16
+
17
+ struct VulkanDepthBuffer {
18
+ VkFormat format;
19
+ VkImage image;
20
+ VkMemoryAllocateInfo memAlloc;
21
+ VkDeviceMemory mem;
22
+ VkImageView view;
23
+ };
24
+
25
+ struct VulkanContext {
26
+ vk::Instance instance;
27
+ vk::PhysicalDevice gpu;
28
+ vk::PhysicalDeviceFeatures gpuFeatures;
29
+ #if VK_KHR_portability_subset
30
+ vk::PhysicalDevicePortabilitySubsetFeaturesKHR gpuPortabilityFeatures;
31
+ #endif
32
+ vk::PhysicalDeviceProperties gpuProperties;
33
+ vk::PhysicalDeviceMemoryProperties memoryProperties;
34
+ vk::Device device;
35
+ vk::CommandPool commandPool;
36
+ vk::Queue queue;
37
+
38
+ bool gpuIsPortabilitySubsetDevice = false;
39
+
40
+ struct {
41
+ bool pvrtc = false;
42
+ bool astc_hdr = false;
43
+ bool astc_3d = false;
44
+ } enabledDeviceExtensions;
45
+ std::vector<VkCommandBuffer> drawCmdBuffers;
46
+ std::vector<VkCommandBuffer> postPresentCmdBuffers;
47
+ std::vector<VkCommandBuffer> prePresentCmdBuffers;
48
+ VkRenderPass renderPass;
49
+ // Pipeline stage flags for the submit info structure
50
+ const VkPipelineStageFlags submitPipelineStages =
51
+ VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
52
+ // Contains command buffers and semaphores to be presented to the queue
53
+ VkSubmitInfo drawCmdSubmitInfo;
54
+
55
+ vk::DescriptorPool descriptorPool;
56
+ VkPipelineCache pipelineCache;
57
+
58
+ VulkanSwapchain swapchain;
59
+ // List of frame buffers (same as number of swap chain images)
60
+ std::vector<VkFramebuffer>framebuffers;
61
+ VulkanDepthBuffer depthBuffer;
62
+
63
+ // Create a new command buffer, opening it for command entry,
64
+ // if requested.
65
+ vk::CommandBuffer createCommandBuffer(vk::CommandBufferLevel level,
66
+ bool begin);
67
+ // End a command buffer, submit it to the queue and free, if requested.
68
+ // Note : Waits for the queue to become idle
69
+ void flushCommandBuffer(vk::CommandBuffer& commandBuffer, bool free);
70
+
71
+ // Create a command buffer for each image in the swap chain.
72
+ bool createDrawCommandBuffers();
73
+ bool createPresentCommandBuffers();
74
+ bool checkDrawCommandBuffers();
75
+ void destroyDrawCommandBuffers();
76
+ void destroyPresentCommandBuffers();
77
+
78
+
79
+ bool getMemoryType(uint32_t typeBits,
80
+ vk::MemoryPropertyFlags requirementsMask,
81
+ uint32_t *typeIndex) const;
82
+ uint32_t getMemoryType(uint32_t typeBits,
83
+ vk::MemoryPropertyFlags requirementsMask) const;
84
+
85
+ // Create a buffer, fill it with data (if != NULL) and bind buffer memory
86
+ bool createBuffer(
87
+ vk::BufferUsageFlags usageFlags,
88
+ vk::MemoryPropertyFlags memoryPropertyFlags,
89
+ vk::DeviceSize size,
90
+ void *data,
91
+ vk::Buffer *buffer,
92
+ vk::DeviceMemory *memory);
93
+ // This version always uses HOST_VISIBLE memory
94
+ bool createBuffer(
95
+ vk::BufferUsageFlags usage,
96
+ vk::DeviceSize size,
97
+ void *data,
98
+ vk::Buffer *buffer,
99
+ vk::DeviceMemory *memory);
100
+ // Overload that assigns buffer info to descriptor
101
+ bool createBuffer(
102
+ vk::BufferUsageFlags usage,
103
+ vk::DeviceSize size,
104
+ void* data,
105
+ vk::Buffer* buffer,
106
+ vk::DeviceMemory* memory,
107
+ vk::DescriptorBufferInfo* descriptor);
108
+ // Overload to pass memory property flags
109
+ bool createBuffer(
110
+ vk::BufferUsageFlags usage,
111
+ vk::MemoryPropertyFlags memoryPropertyFlags,
112
+ vk::DeviceSize size,
113
+ void* data,
114
+ vk::Buffer* buffer,
115
+ vk::DeviceMemory* memory,
116
+ vk::DescriptorBufferInfo* descriptor);
117
+
118
+ vk::PipelineShaderStageCreateInfo loadShader(std::string filename,
119
+ vk::ShaderStageFlagBits stage,
120
+ const char* const modname = "main");
121
+ vk::ShaderModule loadShader(std::string filename);
122
+ uint32_t* readSpv(const char *filename, size_t *pSize);
123
+
124
+ bool gpuSupportsSwizzle() {
125
+ #if VK_KHR_portability_subset
126
+ return !gpuIsPortabilitySubsetDevice
127
+ || gpuPortabilityFeatures.imageViewFormatSwizzle;
128
+ #else
129
+ return true;
130
+ #endif
131
+ }
132
+ };
133
+
134
+ #endif /* VULKAN_TEXTURE_H_229895365400979164311947449304284143508 */
third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/VulkanSwapchain.cpp ADDED
@@ -0,0 +1,434 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* -*- tab-width: 4; -*- */
2
+ /* vi: set sw=2 ts=4 expandtab: */
3
+
4
+ /*
5
+ * Copyright 2017-2020 Mark Callow.
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+
9
+ /**
10
+ * @internal
11
+ * @class VulkanSwapchain
12
+ * @~English
13
+ *
14
+ * @brief Manage the swapchain for a Vulkan app.
15
+ *
16
+ * A swap chain is a collection of image buffers used for rendering
17
+ * The images can then be presented to the windowing system for display.
18
+ *
19
+ * @author Mark Callow, github.com/MarkCallow.
20
+ */
21
+
22
+ #include <stdlib.h>
23
+ #include <string>
24
+ #include <fstream>
25
+ #include <assert.h>
26
+ #include <stdio.h>
27
+ #include <vector>
28
+ #ifdef _WIN32
29
+ #include <windows.h>
30
+ #include <fcntl.h>
31
+ #include <io.h>
32
+ #else
33
+ #endif
34
+
35
+ #include "VulkanSwapchain.h"
36
+
37
+ #include <SDL3/SDL.h>
38
+ #include <SDL3/SDL_vulkan.h>
39
+ #include "AppBaseSDL.h"
40
+ #include "unused.h"
41
+
42
+ #define ERROR_RETURN(msg) \
43
+ (void)SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, theApp->name(), \
44
+ msg, NULL); \
45
+ return false;
46
+
47
+ #define GET_INSTANCE_PROC_ADDR(inst, entrypoint) \
48
+ { \
49
+ pfn##entrypoint = \
50
+ (PFN_vk##entrypoint)vkGetInstanceProcAddr(inst, "vk"#entrypoint); \
51
+ if (pfn##entrypoint == NULL) { \
52
+ ERROR_RETURN("vkGetInstanceProcAddr: unable to find vk"#entrypoint); \
53
+ } \
54
+ }
55
+
56
+ #define GET_DEVICE_PROC_ADDR(device, entrypoint) \
57
+ { \
58
+ pfn##entrypoint = \
59
+ (PFN_vk##entrypoint)vkGetDeviceProcAddr(device, "vk"#entrypoint); \
60
+ if (pfn##entrypoint == NULL) { \
61
+ ERROR_RETURN("vkGetDeviceProcAddr: unable to find vk"#entrypoint); \
62
+ } \
63
+ }
64
+
65
+ // Creates an os specific surface
66
+ // Tries to find a graphics and a present queue
67
+ bool
68
+ VulkanSwapchain::initSurface(SDL_Window* window)
69
+ {
70
+ U_ASSERT_ONLY VkResult err;
71
+
72
+ if (!SDL_Vulkan_CreateSurface(window, instance, nullptr, &surface)) {
73
+ std::string msg = "SDL_CreateVulkanSurface failed: ";
74
+ msg += SDL_GetError();
75
+ ERROR_RETURN(msg.c_str());
76
+ }
77
+
78
+ // Get available queue family properties
79
+ uint32_t queueCount;
80
+ vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueCount, NULL);
81
+ assert(queueCount >= 1);
82
+
83
+ std::vector<VkQueueFamilyProperties> queueProps(queueCount);
84
+ vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueCount,
85
+ queueProps.data());
86
+
87
+ // Iterate over the queues looking for ones which support presenting.
88
+ std::vector<VkBool32> supportsPresent(queueCount);
89
+ for (uint32_t i = 0; i < queueCount; i++) {
90
+ vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, i, surface,
91
+ &supportsPresent[i]);
92
+ }
93
+
94
+ // Search for a graphics- and present-capable queue.
95
+ uint32_t graphicsQueueIndex = UINT32_MAX;
96
+ uint32_t presentQueueIndex = UINT32_MAX;
97
+ for (uint32_t i = 0; i < queueCount; i++) {
98
+ if ((queueProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0)
99
+ {
100
+ if (graphicsQueueIndex == UINT32_MAX)
101
+ {
102
+ graphicsQueueIndex = i;
103
+ }
104
+
105
+ if (supportsPresent[i] == VK_TRUE)
106
+ {
107
+ graphicsQueueIndex = i;
108
+ presentQueueIndex = i;
109
+ break;
110
+ }
111
+ }
112
+ }
113
+ if (presentQueueIndex == UINT32_MAX) {
114
+ // If there's no queue that supports both present and graphics
115
+ // try to find a separate present queue
116
+ for (uint32_t i = 0; i < queueCount; ++i)
117
+ {
118
+ if (supportsPresent[i] == VK_TRUE)
119
+ {
120
+ presentQueueIndex = i;
121
+ break;
122
+ }
123
+ }
124
+ }
125
+
126
+ // Exit if either a graphics or a presenting queue hasn't been found
127
+ if (graphicsQueueIndex == UINT32_MAX
128
+ || presentQueueIndex == UINT32_MAX)
129
+ {
130
+ ERROR_RETURN("Could not find a graphics or presenting queue!");
131
+ }
132
+
133
+ // TODO: Add support for separate graphics and presenting queue
134
+ if (graphicsQueueIndex != presentQueueIndex)
135
+ {
136
+ ERROR_RETURN("Separate graphics and present queues not yet supported!");
137
+ }
138
+
139
+ queueIndex = graphicsQueueIndex;
140
+
141
+ // Get list of supported surface formats
142
+ uint32_t formatCount;
143
+ err = vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface,
144
+ &formatCount, NULL);
145
+ assert(err == VK_SUCCESS);
146
+ assert(formatCount > 0);
147
+
148
+ std::vector<VkSurfaceFormatKHR> surfaceFormats(formatCount);
149
+ err = vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface,
150
+ &formatCount,
151
+ surfaceFormats.data());
152
+ assert(err == VK_SUCCESS);
153
+
154
+ // If the surface format list only includes one entry with
155
+ // VK_FORMAT_UNDEFINED, there is no preferred format.
156
+ // Assume VK_FORMAT_B8G8R8A8_RGB.
157
+ // TODO: Consider passing in desired format from app.
158
+ if ((formatCount == 1) && (surfaceFormats[0].format == VK_FORMAT_UNDEFINED))
159
+ {
160
+ colorFormat = VK_FORMAT_B8G8R8A8_SRGB;
161
+ }
162
+ else
163
+ {
164
+ assert(formatCount >= 1);
165
+ uint32_t i;
166
+ for (i = 0; i < formatCount; i++) {
167
+ if (surfaceFormats[i].format == VK_FORMAT_B8G8R8A8_SRGB) {
168
+ break;
169
+ }
170
+ }
171
+ if (i == formatCount) {
172
+ // Pick the first available, if no SRGB.
173
+ // FIXME probably should raise an error...
174
+ i = 0;
175
+ }
176
+ colorFormat = surfaceFormats[i].format;
177
+ }
178
+ colorSpace = surfaceFormats[0].colorSpace;
179
+ return true;
180
+ }
181
+
182
+
183
+ // Connect to the instance and device and get all required function pointers
184
+ bool
185
+ VulkanSwapchain::connectDevice(VkDevice targetDevice)
186
+ {
187
+ this->device = targetDevice;
188
+ #if USE_FUNCPTRS_FOR_KHR_EXTS
189
+ GET_DEVICE_PROC_ADDR(device, CreateSwapchainKHR);
190
+ GET_DEVICE_PROC_ADDR(device, DestroySwapchainKHR);
191
+ GET_DEVICE_PROC_ADDR(device, GetSwapchainImagesKHR);
192
+ GET_DEVICE_PROC_ADDR(device, AcquireNextImageKHR);
193
+ GET_DEVICE_PROC_ADDR(device, QueuePresentKHR);
194
+ #endif
195
+ return true;
196
+ }
197
+
198
+
199
+ // Connect to the instance and device and get all required function pointers
200
+ bool
201
+ VulkanSwapchain::connectInstance(VkInstance targetInstance,
202
+ VkPhysicalDevice targetPhysicalDevice)
203
+ {
204
+ this->instance = targetInstance;
205
+ this->physicalDevice = targetPhysicalDevice;
206
+ #if USE_FUNCPTRS_FOR_KHR_EXTS
207
+ GET_INSTANCE_PROC_ADDR(instance, GetPhysicalDeviceSurfaceSupportKHR);
208
+ GET_INSTANCE_PROC_ADDR(instance, GetPhysicalDeviceSurfaceCapabilitiesKHR);
209
+ GET_INSTANCE_PROC_ADDR(instance, GetPhysicalDeviceSurfaceFormatsKHR);
210
+ GET_INSTANCE_PROC_ADDR(instance, GetPhysicalDeviceSurfacePresentModesKHR);
211
+ #endif
212
+ return true;
213
+ }
214
+
215
+
216
+ // Create the swap chain and get images with given width and height
217
+ void
218
+ VulkanSwapchain::create(uint32_t *width, uint32_t *height,
219
+ bool vsync)
220
+ {
221
+ U_ASSERT_ONLY VkResult err;
222
+ VkSwapchainKHR oldSwapchain = swapchain;
223
+
224
+ // Get physical device surface properties and formats
225
+ VkSurfaceCapabilitiesKHR surfCaps;
226
+ err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface,
227
+ &surfCaps);
228
+ assert(err == VK_SUCCESS);
229
+
230
+ // Get available present modes
231
+ uint32_t presentModeCount;
232
+ err = vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface,
233
+ &presentModeCount, NULL);
234
+ assert(err == VK_SUCCESS);
235
+ assert(presentModeCount > 0);
236
+
237
+ std::vector<VkPresentModeKHR> presentModes(presentModeCount);
238
+
239
+ err = vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface,
240
+ &presentModeCount,
241
+ presentModes.data());
242
+ assert(err == VK_SUCCESS);
243
+
244
+ VkExtent2D swapchainExtent = {};
245
+ // width and height are either both 0xFFFFFFFF, or both not 0xFFFFFFFF.
246
+ if (surfCaps.currentExtent.width == UINT32_MAX)
247
+ {
248
+ // If the surface size is undefined, the size is set to
249
+ // the size of the images requested.
250
+ swapchainExtent.width = *width;
251
+ swapchainExtent.height = *height;
252
+ }
253
+ else
254
+ {
255
+ swapchainExtent = surfCaps.currentExtent;
256
+ *width = surfCaps.currentExtent.width;
257
+ *height = surfCaps.currentExtent.height;
258
+ }
259
+
260
+
261
+ // Select a present mode for the swapchain
262
+
263
+ // The VK_PRESENT_MODE_FIFO_KHR mode must always be present as per spec
264
+ // This mode waits for the vertical blank ("v-sync")
265
+ VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR;
266
+
267
+ // If v-sync is not requested, try to find a mailbox mode if present
268
+ // It's the lowest latency non-tearing present mode available
269
+ if (!vsync)
270
+ {
271
+ for (size_t i = 0; i < presentModeCount; i++)
272
+ {
273
+ if (presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR)
274
+ {
275
+ swapchainPresentMode = VK_PRESENT_MODE_MAILBOX_KHR;
276
+ break;
277
+ }
278
+ if ((swapchainPresentMode != VK_PRESENT_MODE_MAILBOX_KHR)
279
+ && (presentModes[i] == VK_PRESENT_MODE_IMMEDIATE_KHR))
280
+ {
281
+ swapchainPresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
282
+ }
283
+ }
284
+ }
285
+
286
+ // Determine the number of images
287
+ uint32_t desiredNumberOfSwapchainImages = surfCaps.minImageCount + 1;
288
+ if ((surfCaps.maxImageCount > 0)
289
+ && (desiredNumberOfSwapchainImages > surfCaps.maxImageCount))
290
+ {
291
+ desiredNumberOfSwapchainImages = surfCaps.maxImageCount;
292
+ }
293
+
294
+ VkSurfaceTransformFlagsKHR preTransform;
295
+ if (surfCaps.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) {
296
+ preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
297
+ } else {
298
+ preTransform = surfCaps.currentTransform;
299
+ }
300
+
301
+ VkSwapchainCreateInfoKHR swapchainCI = {};
302
+ swapchainCI.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
303
+ swapchainCI.pNext = NULL;
304
+ swapchainCI.surface = surface;
305
+ swapchainCI.minImageCount = desiredNumberOfSwapchainImages;
306
+ swapchainCI.imageFormat = colorFormat;
307
+ swapchainCI.imageColorSpace = colorSpace;
308
+ swapchainCI.imageExtent = { swapchainExtent.width, swapchainExtent.height };
309
+ swapchainCI.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
310
+ swapchainCI.preTransform = (VkSurfaceTransformFlagBitsKHR)preTransform;
311
+ swapchainCI.imageArrayLayers = 1;
312
+ swapchainCI.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
313
+ swapchainCI.queueFamilyIndexCount = 0;
314
+ swapchainCI.pQueueFamilyIndices = NULL;
315
+ swapchainCI.presentMode = swapchainPresentMode;
316
+ swapchainCI.oldSwapchain = oldSwapchain;
317
+ swapchainCI.clipped = true;
318
+ swapchainCI.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
319
+
320
+ err = vkCreateSwapchainKHR(device, &swapchainCI, nullptr, &swapchain);
321
+ assert(err == VK_SUCCESS);
322
+
323
+ // If an existing swap chain is re-created, destroy the old swap chain
324
+ // This also cleans up all the presentable images
325
+ if (oldSwapchain != VK_NULL_HANDLE)
326
+ {
327
+ for (uint32_t i = 0; i < imageCount; i++)
328
+ {
329
+ vkDestroyImageView(device, buffers[i].view, nullptr);
330
+ }
331
+ vkDestroySwapchainKHR(device, oldSwapchain, nullptr);
332
+ }
333
+
334
+ err = vkGetSwapchainImagesKHR(device, swapchain, &imageCount, NULL);
335
+ assert(err == VK_SUCCESS);
336
+
337
+ // Get the swap chain images
338
+ images.resize(imageCount);
339
+ err = vkGetSwapchainImagesKHR(device, swapchain,
340
+ &imageCount, images.data());
341
+ assert(err == VK_SUCCESS);
342
+
343
+ // Get the swap chain buffers containing the image and imageview
344
+ buffers.resize(imageCount);
345
+ for (uint32_t i = 0; i < imageCount; i++)
346
+ {
347
+ VkImageViewCreateInfo colorAttachmentView = {};
348
+ colorAttachmentView.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
349
+ colorAttachmentView.pNext = NULL;
350
+ colorAttachmentView.format = colorFormat;
351
+ colorAttachmentView.components = {
352
+ VK_COMPONENT_SWIZZLE_IDENTITY,
353
+ VK_COMPONENT_SWIZZLE_IDENTITY,
354
+ VK_COMPONENT_SWIZZLE_IDENTITY,
355
+ VK_COMPONENT_SWIZZLE_IDENTITY
356
+ };
357
+ colorAttachmentView.subresourceRange.aspectMask
358
+ = VK_IMAGE_ASPECT_COLOR_BIT;
359
+ colorAttachmentView.subresourceRange.baseMipLevel = 0;
360
+ colorAttachmentView.subresourceRange.levelCount = 1;
361
+ colorAttachmentView.subresourceRange.baseArrayLayer = 0;
362
+ colorAttachmentView.subresourceRange.layerCount = 1;
363
+ colorAttachmentView.viewType = VK_IMAGE_VIEW_TYPE_2D;
364
+ colorAttachmentView.flags = 0;
365
+
366
+ buffers[i].image = images[i];
367
+
368
+ colorAttachmentView.image = buffers[i].image;
369
+
370
+ err = vkCreateImageView(device, &colorAttachmentView, nullptr,
371
+ &buffers[i].view);
372
+ assert(err == VK_SUCCESS);
373
+ }
374
+ }
375
+
376
+
377
+ // Acquires the next image in the swap chain
378
+ VkResult
379
+ VulkanSwapchain::acquireNextImage(VkSemaphore presentCompleteSemaphore,
380
+ uint32_t *currentBuffer)
381
+ {
382
+ return vkAcquireNextImageKHR(device, swapchain, UINT64_MAX,
383
+ presentCompleteSemaphore,
384
+ (VkFence)nullptr,
385
+ currentBuffer);
386
+ }
387
+
388
+
389
+ // Present the current image to the queue
390
+ VkResult
391
+ VulkanSwapchain::queuePresent(VkQueue queue, uint32_t currentBuffer)
392
+ {
393
+ VkPresentInfoKHR presentInfo = {};
394
+ presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
395
+ presentInfo.pNext = NULL;
396
+ presentInfo.swapchainCount = 1;
397
+ presentInfo.pSwapchains = &swapchain;
398
+ presentInfo.pImageIndices = &currentBuffer;
399
+ return vkQueuePresentKHR(queue, &presentInfo);
400
+ }
401
+
402
+
403
+ // Present the current image to the queue when semaphore signaled.
404
+ VkResult
405
+ VulkanSwapchain::queuePresent(VkQueue queue, uint32_t currentBuffer,
406
+ VkSemaphore waitSemaphore)
407
+ {
408
+ VkPresentInfoKHR presentInfo = {};
409
+ presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
410
+ presentInfo.pNext = NULL;
411
+ presentInfo.swapchainCount = 1;
412
+ presentInfo.pSwapchains = &swapchain;
413
+ presentInfo.pImageIndices = &currentBuffer;
414
+ if (waitSemaphore != VK_NULL_HANDLE)
415
+ {
416
+ presentInfo.pWaitSemaphores = &waitSemaphore;
417
+ presentInfo.waitSemaphoreCount = 1;
418
+ }
419
+ return vkQueuePresentKHR(queue, &presentInfo);
420
+ }
421
+
422
+
423
+ // Free all Vulkan resources used by the swap chain
424
+ void
425
+ VulkanSwapchain::cleanup()
426
+ {
427
+ for (uint32_t i = 0; i < imageCount; i++)
428
+ {
429
+ vkDestroyImageView(device, buffers[i].view, nullptr);
430
+ }
431
+ vkDestroySwapchainKHR(device, swapchain, nullptr);
432
+ vkDestroySurfaceKHR(instance, surface, nullptr);
433
+ }
434
+
third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/VulkanSwapchain.h ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* -*- tab-width: 4; -*- */
2
+ /* vi: set sw=2 ts=4 expandtab: */
3
+
4
+ /*
5
+ * Copyright 2017-2020 Mark Callow.
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+
9
+ #pragma once
10
+
11
+ #include <vector>
12
+
13
+ #include <vulkan/vulkan.h>
14
+
15
+ #if !defined(USE_FUNCPTRS_FOR_KHR_EXTS)
16
+ #define USE_FUNCPTRS_FOR_KHR_EXTS 0
17
+ #endif
18
+
19
+ typedef struct _SwapchainBuffers {
20
+ VkImage image;
21
+ VkImageView view;
22
+ } SwapchainBuffer;
23
+
24
+ class VulkanSwapchain
25
+ {
26
+ public:
27
+ VkFormat colorFormat;
28
+ VkColorSpaceKHR colorSpace;
29
+
30
+ VkSwapchainKHR swapchain = VK_NULL_HANDLE;
31
+
32
+ uint32_t imageCount;
33
+ std::vector<VkImage> images;
34
+ std::vector<SwapchainBuffer> buffers;
35
+
36
+ // Index of the detected graphics- and present-capable device queue.
37
+ uint32_t queueIndex = UINT32_MAX;
38
+
39
+ // Creates an OS specific surface.
40
+ // Looks for a graphics and a present queue
41
+ bool initSurface(struct SDL_Window* window);
42
+
43
+ // Connect to device and get required device function pointers.
44
+ bool connectDevice(VkDevice device);
45
+
46
+ // Connect to instance and get required instance function pointers.
47
+ bool connectInstance(VkInstance instance,
48
+ VkPhysicalDevice physicalDevice);
49
+
50
+ // Create the swap chain and get images with given width and height
51
+ void create(uint32_t *width, uint32_t *height,
52
+ bool vsync = false);
53
+
54
+ // Acquires the next image in the swap chain
55
+ VkResult acquireNextImage(VkSemaphore presentCompleteSemaphore,
56
+ uint32_t *currentBuffer);
57
+
58
+ // Present the current image to the queue
59
+ VkResult queuePresent(VkQueue queue, uint32_t currentBuffer);
60
+
61
+ // Present the current image to the queue
62
+ VkResult queuePresent(VkQueue queue, uint32_t currentBuffer,
63
+ VkSemaphore waitSemaphore);
64
+
65
+
66
+ // Free all Vulkan resources used by the swap chain
67
+ void cleanup();
68
+
69
+ private:
70
+ VkInstance instance;
71
+ VkDevice device;
72
+ VkPhysicalDevice physicalDevice;
73
+ VkSurfaceKHR surface;
74
+ #if USE_FUNCPTRS_FOR_KHR_EXTS
75
+ PFN_vkGetPhysicalDeviceSurfaceSupportKHR
76
+ pfnGetPhysicalDeviceSurfaceSupportKHR;
77
+ PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR
78
+ pfnGetPhysicalDeviceSurfaceCapabilitiesKHR;
79
+ PFN_vkGetPhysicalDeviceSurfaceFormatsKHR
80
+ pfnGetPhysicalDeviceSurfaceFormatsKHR;
81
+ PFN_vkGetPhysicalDeviceSurfacePresentModesKHR
82
+ pfnGetPhysicalDeviceSurfacePresentModesKHR;
83
+
84
+ PFN_vkCreateSwapchainKHR pfnCreateSwapchainKHR;
85
+ PFN_vkDestroySwapchainKHR pfnDestroySwapchainKHR;
86
+ PFN_vkGetSwapchainImagesKHR pfnGetSwapchainImagesKHR;
87
+ PFN_vkAcquireNextImageKHR pfnAcquireNextImageKHR;
88
+ PFN_vkQueuePresentKHR pfnQueuePresentKHR;
89
+
90
+ #define vkGetPhysicalDeviceSurfaceSupportKHR \
91
+ pfnGetPhysicalDeviceSurfaceSupportKHR
92
+ #define vkGetPhysicalDeviceSurfaceCapabilitiesKHR \
93
+ pfnGetPhysicalDeviceSurfaceCapabilitiesKHR
94
+ #define vkGetPhysicalDeviceSurfaceFormatsKHR \
95
+ pfnGetPhysicalDeviceSurfaceFormatsKHR
96
+ #define vkGetPhysicalDeviceSurfacePresentModesKHR \
97
+ pfnGetPhysicalDeviceSurfacePresentModesKHR
98
+
99
+ #define vkCreateSwapchainKHR pfnCreateSwapchainKHR
100
+ #define vkDestroySwapchainKHR pfnDestroySwapchainKHR
101
+ #define vkGetSwapchainImagesKHR pfnGetSwapchainImagesKHR
102
+ #define vkAcquireNextImageKHR pfnAcquireNextImageKHR
103
+ #define vkQueuePresentKHR pfnQueuePresentKHR
104
+ #endif
105
+ };
third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/mac/vulkan/README.md ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ <!-- Copyright 2024 Mark Callow -->
2
+ <!-- SPDX-License-Identifier: Apache-2.0 -->
3
+
4
+ # Vulkan ICD and Explicit Layer Manifest Files
5
+
6
+ These were copied from `macOS/share/vulkan` in the Vulkan SDK and have been
7
+ modified for inclusion in a macOS application bundle to cause the Vulkan loader
8
+ to find the libraries within the bundle.
third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/mac/vulkan/explicit_layer.d/VkLayer_khronos_validation.json ADDED
@@ -0,0 +1,1709 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "file_format_version": "1.2.0",
3
+ "layer": {
4
+ "name": "VK_LAYER_KHRONOS_validation",
5
+ "type": "GLOBAL",
6
+ "library_path": "../../../Frameworks/libVkLayer_khronos_validation.dylib",
7
+ "api_version": "1.3.283",
8
+ "implementation_version": "1",
9
+ "description": "Khronos Validation Layer",
10
+ "introduction": "The main, comprehensive Khronos validation layer.\n\nVulkan is an Explicit API, enabling direct control over how GPUs actually work. By design, minimal error checking is done inside a Vulkan driver. Applications have full control and responsibility for correct operation. Any errors in how Vulkan is used can result in a crash. \n\nThe Khronos Valiation Layer can be enabled to assist development by enabling developers to verify their applications correctly use the Vulkan API.",
11
+ "platforms": [
12
+ "WINDOWS",
13
+ "LINUX",
14
+ "ANDROID",
15
+ "MACOS"
16
+ ],
17
+ "url": "https://vulkan.lunarg.com/doc/sdk/latest/windows/khronos_validation_layer.html",
18
+ "instance_extensions": [
19
+ {
20
+ "name": "VK_EXT_debug_report",
21
+ "spec_version": "9"
22
+ },
23
+ {
24
+ "name": "VK_EXT_debug_utils",
25
+ "spec_version": "1"
26
+ },
27
+ {
28
+ "name": "VK_EXT_layer_settings",
29
+ "spec_version": "2"
30
+ },
31
+ {
32
+ "name": "VK_EXT_validation_features",
33
+ "spec_version": "2"
34
+ }
35
+ ],
36
+ "device_extensions": [
37
+ {
38
+ "name": "VK_EXT_debug_marker",
39
+ "spec_version": "4",
40
+ "entrypoints": [
41
+ "vkDebugMarkerSetObjectTagEXT",
42
+ "vkDebugMarkerSetObjectNameEXT",
43
+ "vkCmdDebugMarkerBeginEXT",
44
+ "vkCmdDebugMarkerEndEXT",
45
+ "vkCmdDebugMarkerInsertEXT"
46
+ ]
47
+ },
48
+ {
49
+ "name": "VK_EXT_validation_cache",
50
+ "spec_version": "1",
51
+ "entrypoints": [
52
+ "vkCreateValidationCacheEXT",
53
+ "vkDestroyValidationCacheEXT",
54
+ "vkGetValidationCacheDataEXT",
55
+ "vkMergeValidationCachesEXT"
56
+ ]
57
+ },
58
+ {
59
+ "name": "VK_EXT_tooling_info",
60
+ "spec_version": "1",
61
+ "entrypoints": [
62
+ "vkGetPhysicalDeviceToolPropertiesEXT"
63
+ ]
64
+ }
65
+ ],
66
+ "features": {
67
+ "presets": [
68
+ {
69
+ "label": "Standard",
70
+ "description": "Good default validation setup that balance validation coverage and performance.",
71
+ "platforms": [
72
+ "WINDOWS",
73
+ "LINUX",
74
+ "MACOS",
75
+ "ANDROID"
76
+ ],
77
+ "status": "STABLE",
78
+ "settings": [
79
+ {
80
+ "key": "validate_core",
81
+ "value": true
82
+ },
83
+ {
84
+ "key": "check_image_layout",
85
+ "value": true
86
+ },
87
+ {
88
+ "key": "check_command_buffer",
89
+ "value": true
90
+ },
91
+ {
92
+ "key": "check_object_in_use",
93
+ "value": true
94
+ },
95
+ {
96
+ "key": "check_query",
97
+ "value": true
98
+ },
99
+ {
100
+ "key": "check_shaders",
101
+ "value": true
102
+ },
103
+ {
104
+ "key": "check_shaders_caching",
105
+ "value": true
106
+ },
107
+ {
108
+ "key": "unique_handles",
109
+ "value": true
110
+ },
111
+ {
112
+ "key": "object_lifetime",
113
+ "value": true
114
+ },
115
+ {
116
+ "key": "stateless_param",
117
+ "value": true
118
+ },
119
+ {
120
+ "key": "thread_safety",
121
+ "value": false
122
+ },
123
+ {
124
+ "key": "validate_sync",
125
+ "value": false
126
+ },
127
+ {
128
+ "key": "validate_gpu_based",
129
+ "value": "GPU_BASED_NONE"
130
+ },
131
+ {
132
+ "key": "validate_best_practices",
133
+ "value": false
134
+ },
135
+ {
136
+ "key": "report_flags",
137
+ "value": [
138
+ "error"
139
+ ]
140
+ }
141
+ ]
142
+ },
143
+ {
144
+ "label": "Reduced-Overhead",
145
+ "description": "Disables some checks in the interest of better performance.",
146
+ "platforms": [
147
+ "WINDOWS",
148
+ "LINUX",
149
+ "MACOS"
150
+ ],
151
+ "status": "STABLE",
152
+ "settings": [
153
+ {
154
+ "key": "validate_core",
155
+ "value": true
156
+ },
157
+ {
158
+ "key": "check_image_layout",
159
+ "value": false
160
+ },
161
+ {
162
+ "key": "check_command_buffer",
163
+ "value": false
164
+ },
165
+ {
166
+ "key": "check_object_in_use",
167
+ "value": false
168
+ },
169
+ {
170
+ "key": "check_query",
171
+ "value": false
172
+ },
173
+ {
174
+ "key": "check_shaders",
175
+ "value": true
176
+ },
177
+ {
178
+ "key": "check_shaders_caching",
179
+ "value": true
180
+ },
181
+ {
182
+ "key": "unique_handles",
183
+ "value": false
184
+ },
185
+ {
186
+ "key": "object_lifetime",
187
+ "value": true
188
+ },
189
+ {
190
+ "key": "stateless_param",
191
+ "value": true
192
+ },
193
+ {
194
+ "key": "thread_safety",
195
+ "value": false
196
+ },
197
+ {
198
+ "key": "validate_sync",
199
+ "value": false
200
+ },
201
+ {
202
+ "key": "validate_gpu_based",
203
+ "value": "GPU_BASED_NONE"
204
+ },
205
+ {
206
+ "key": "validate_best_practices",
207
+ "value": false
208
+ },
209
+ {
210
+ "key": "report_flags",
211
+ "value": [
212
+ "error"
213
+ ]
214
+ }
215
+ ]
216
+ },
217
+ {
218
+ "label": "Best Practices",
219
+ "description": "Provides warnings on valid API usage that is potential API misuse.",
220
+ "platforms": [
221
+ "WINDOWS",
222
+ "LINUX",
223
+ "MACOS",
224
+ "ANDROID"
225
+ ],
226
+ "status": "STABLE",
227
+ "settings": [
228
+ {
229
+ "key": "validate_core",
230
+ "value": false
231
+ },
232
+ {
233
+ "key": "check_image_layout",
234
+ "value": false
235
+ },
236
+ {
237
+ "key": "check_command_buffer",
238
+ "value": false
239
+ },
240
+ {
241
+ "key": "check_object_in_use",
242
+ "value": false
243
+ },
244
+ {
245
+ "key": "check_query",
246
+ "value": false
247
+ },
248
+ {
249
+ "key": "check_shaders",
250
+ "value": false
251
+ },
252
+ {
253
+ "key": "check_shaders_caching",
254
+ "value": false
255
+ },
256
+ {
257
+ "key": "unique_handles",
258
+ "value": false
259
+ },
260
+ {
261
+ "key": "object_lifetime",
262
+ "value": false
263
+ },
264
+ {
265
+ "key": "stateless_param",
266
+ "value": false
267
+ },
268
+ {
269
+ "key": "thread_safety",
270
+ "value": false
271
+ },
272
+ {
273
+ "key": "validate_sync",
274
+ "value": false
275
+ },
276
+ {
277
+ "key": "validate_gpu_based",
278
+ "value": "GPU_BASED_NONE"
279
+ },
280
+ {
281
+ "key": "validate_best_practices",
282
+ "value": true
283
+ },
284
+ {
285
+ "key": "report_flags",
286
+ "value": [
287
+ "error",
288
+ "warn",
289
+ "perf"
290
+ ]
291
+ }
292
+ ]
293
+ },
294
+ {
295
+ "label": "Synchronization",
296
+ "description": "Identify resource access conflicts due to missing or incorrect synchronization operations between actions reading or writing the same regions of memory.",
297
+ "platforms": [
298
+ "WINDOWS",
299
+ "LINUX",
300
+ "MACOS",
301
+ "ANDROID"
302
+ ],
303
+ "status": "STABLE",
304
+ "settings": [
305
+ {
306
+ "key": "validate_core",
307
+ "value": false
308
+ },
309
+ {
310
+ "key": "check_image_layout",
311
+ "value": false
312
+ },
313
+ {
314
+ "key": "check_command_buffer",
315
+ "value": false
316
+ },
317
+ {
318
+ "key": "check_object_in_use",
319
+ "value": false
320
+ },
321
+ {
322
+ "key": "check_query",
323
+ "value": false
324
+ },
325
+ {
326
+ "key": "check_shaders",
327
+ "value": false
328
+ },
329
+ {
330
+ "key": "check_shaders_caching",
331
+ "value": false
332
+ },
333
+ {
334
+ "key": "unique_handles",
335
+ "value": true
336
+ },
337
+ {
338
+ "key": "object_lifetime",
339
+ "value": false
340
+ },
341
+ {
342
+ "key": "stateless_param",
343
+ "value": false
344
+ },
345
+ {
346
+ "key": "thread_safety",
347
+ "value": true
348
+ },
349
+ {
350
+ "key": "validate_sync",
351
+ "value": true
352
+ },
353
+ {
354
+ "key": "sync_queue_submit",
355
+ "value": true
356
+ },
357
+ {
358
+ "key": "validate_gpu_based",
359
+ "value": "GPU_BASED_NONE"
360
+ },
361
+ {
362
+ "key": "validate_best_practices",
363
+ "value": false
364
+ },
365
+ {
366
+ "key": "report_flags",
367
+ "value": [
368
+ "error"
369
+ ]
370
+ }
371
+ ]
372
+ },
373
+ {
374
+ "label": "GPU-Assisted",
375
+ "description": "Check for API usage errors at shader execution time.",
376
+ "platforms": [
377
+ "WINDOWS",
378
+ "LINUX"
379
+ ],
380
+ "status": "STABLE",
381
+ "settings": [
382
+ {
383
+ "key": "validate_core",
384
+ "value": false
385
+ },
386
+ {
387
+ "key": "check_image_layout",
388
+ "value": false
389
+ },
390
+ {
391
+ "key": "check_command_buffer",
392
+ "value": false
393
+ },
394
+ {
395
+ "key": "check_object_in_use",
396
+ "value": false
397
+ },
398
+ {
399
+ "key": "check_query",
400
+ "value": false
401
+ },
402
+ {
403
+ "key": "check_shaders",
404
+ "value": false
405
+ },
406
+ {
407
+ "key": "check_shaders_caching",
408
+ "value": false
409
+ },
410
+ {
411
+ "key": "unique_handles",
412
+ "value": false
413
+ },
414
+ {
415
+ "key": "object_lifetime",
416
+ "value": false
417
+ },
418
+ {
419
+ "key": "stateless_param",
420
+ "value": false
421
+ },
422
+ {
423
+ "key": "thread_safety",
424
+ "value": false
425
+ },
426
+ {
427
+ "key": "validate_sync",
428
+ "value": false
429
+ },
430
+ {
431
+ "key": "validate_gpu_based",
432
+ "value": "GPU_BASED_GPU_ASSISTED"
433
+ },
434
+ {
435
+ "key": "gpuav_reserve_binding_slot",
436
+ "value": true
437
+ },
438
+ {
439
+ "key": "validate_best_practices",
440
+ "value": false
441
+ },
442
+ {
443
+ "key": "report_flags",
444
+ "value": [
445
+ "error"
446
+ ]
447
+ }
448
+ ]
449
+ },
450
+ {
451
+ "label": "Debug Printf",
452
+ "description": "Debug shader code by \"printing\" any values of interest to the debug callback or stdout.",
453
+ "platforms": [
454
+ "WINDOWS",
455
+ "LINUX"
456
+ ],
457
+ "status": "STABLE",
458
+ "settings": [
459
+ {
460
+ "key": "validate_core",
461
+ "value": false
462
+ },
463
+ {
464
+ "key": "check_image_layout",
465
+ "value": false
466
+ },
467
+ {
468
+ "key": "check_command_buffer",
469
+ "value": false
470
+ },
471
+ {
472
+ "key": "check_object_in_use",
473
+ "value": false
474
+ },
475
+ {
476
+ "key": "check_query",
477
+ "value": false
478
+ },
479
+ {
480
+ "key": "check_shaders",
481
+ "value": false
482
+ },
483
+ {
484
+ "key": "check_shaders_caching",
485
+ "value": false
486
+ },
487
+ {
488
+ "key": "unique_handles",
489
+ "value": false
490
+ },
491
+ {
492
+ "key": "object_lifetime",
493
+ "value": false
494
+ },
495
+ {
496
+ "key": "stateless_param",
497
+ "value": false
498
+ },
499
+ {
500
+ "key": "thread_safety",
501
+ "value": false
502
+ },
503
+ {
504
+ "key": "validate_sync",
505
+ "value": false
506
+ },
507
+ {
508
+ "key": "validate_gpu_based",
509
+ "value": "GPU_BASED_DEBUG_PRINTF"
510
+ },
511
+ {
512
+ "key": "validate_best_practices",
513
+ "value": false
514
+ },
515
+ {
516
+ "key": "report_flags",
517
+ "value": [
518
+ "error"
519
+ ]
520
+ }
521
+ ]
522
+ }
523
+ ],
524
+ "settings": [
525
+ {
526
+ "key": "validation_control",
527
+ "label": "Validation Areas",
528
+ "description": "Control of the Validation layer validation",
529
+ "type": "GROUP",
530
+ "expanded": true,
531
+ "settings": [
532
+ {
533
+ "key": "fine_grained_locking",
534
+ "env": "VK_LAYER_FINE_GRAINED_LOCKING",
535
+ "label": "Fine Grained Locking",
536
+ "description": "Enable fine grained locking for Core Validation, which should improve performance in multithreaded applications. This setting allows the optimization to be disabled for debugging.",
537
+ "type": "BOOL",
538
+ "default": true,
539
+ "platforms": [
540
+ "WINDOWS",
541
+ "LINUX",
542
+ "MACOS",
543
+ "ANDROID"
544
+ ]
545
+ },
546
+ {
547
+ "key": "validate_core",
548
+ "label": "Core",
549
+ "description": "The main, heavy-duty validation checks. This may be valuable early in the development cycle to reduce validation output while correcting parameter/object usage errors.",
550
+ "type": "BOOL",
551
+ "default": true,
552
+ "settings": [
553
+ {
554
+ "key": "check_image_layout",
555
+ "label": "Image Layout",
556
+ "description": "Check that the layout of each image subresource is correct whenever it is used by a command buffer. These checks are very CPU intensive for some applications.",
557
+ "type": "BOOL",
558
+ "default": true,
559
+ "dependence": {
560
+ "mode": "ALL",
561
+ "settings": [
562
+ {
563
+ "key": "validate_core",
564
+ "value": true
565
+ }
566
+ ]
567
+ }
568
+ },
569
+ {
570
+ "key": "check_command_buffer",
571
+ "label": "Command Buffer State",
572
+ "description": "Check that all Vulkan objects used by a command buffer have not been destroyed. These checks can be CPU intensive for some applications.",
573
+ "type": "BOOL",
574
+ "default": true,
575
+ "dependence": {
576
+ "mode": "ALL",
577
+ "settings": [
578
+ {
579
+ "key": "validate_core",
580
+ "value": true
581
+ }
582
+ ]
583
+ }
584
+ },
585
+ {
586
+ "key": "check_object_in_use",
587
+ "label": "Object in Use",
588
+ "description": "Check that Vulkan objects are not in use by a command buffer when they are destroyed.",
589
+ "type": "BOOL",
590
+ "default": true,
591
+ "dependence": {
592
+ "mode": "ALL",
593
+ "settings": [
594
+ {
595
+ "key": "validate_core",
596
+ "value": true
597
+ }
598
+ ]
599
+ }
600
+ },
601
+ {
602
+ "key": "check_query",
603
+ "label": "Query",
604
+ "description": "Checks for commands that use VkQueryPool objects.",
605
+ "type": "BOOL",
606
+ "default": true,
607
+ "dependence": {
608
+ "mode": "ALL",
609
+ "settings": [
610
+ {
611
+ "key": "validate_core",
612
+ "value": true
613
+ }
614
+ ]
615
+ }
616
+ },
617
+ {
618
+ "key": "check_shaders",
619
+ "label": "Shader",
620
+ "description": "Shader checks. These checks can be CPU intensive during application start up, especially if Shader Validation Caching is also disabled.",
621
+ "type": "BOOL",
622
+ "default": true,
623
+ "expanded": true,
624
+ "dependence": {
625
+ "mode": "ALL",
626
+ "settings": [
627
+ {
628
+ "key": "validate_core",
629
+ "value": true
630
+ }
631
+ ]
632
+ },
633
+ "settings": [
634
+ {
635
+ "key": "check_shaders_caching",
636
+ "label": "Caching",
637
+ "description": "Enable caching of shader validation results.",
638
+ "type": "BOOL",
639
+ "default": true,
640
+ "dependence": {
641
+ "mode": "ALL",
642
+ "settings": [
643
+ {
644
+ "key": "validate_core",
645
+ "value": true
646
+ },
647
+ {
648
+ "key": "check_shaders",
649
+ "value": true
650
+ }
651
+ ]
652
+ }
653
+ }
654
+ ]
655
+ }
656
+ ]
657
+ },
658
+ {
659
+ "key": "unique_handles",
660
+ "label": "Handle Wrapping",
661
+ "description": "Handle wrapping checks. Disable this feature if you are exerience crashes when creating new extensions or developing new Vulkan objects/structures.",
662
+ "type": "BOOL",
663
+ "default": true,
664
+ "status": "STABLE",
665
+ "platforms": [
666
+ "WINDOWS",
667
+ "LINUX",
668
+ "MACOS",
669
+ "ANDROID"
670
+ ]
671
+ },
672
+ {
673
+ "key": "object_lifetime",
674
+ "label": "Object Lifetime",
675
+ "description": "Object tracking checks. This may not always be necessary late in a development cycle.",
676
+ "type": "BOOL",
677
+ "default": true,
678
+ "status": "STABLE",
679
+ "platforms": [
680
+ "WINDOWS",
681
+ "LINUX",
682
+ "MACOS",
683
+ "ANDROID"
684
+ ]
685
+ },
686
+ {
687
+ "key": "stateless_param",
688
+ "label": "Stateless Parameter",
689
+ "description": "Stateless parameter checks. This may not always be necessary late in a development cycle.",
690
+ "type": "BOOL",
691
+ "default": true,
692
+ "status": "STABLE",
693
+ "platforms": [
694
+ "WINDOWS",
695
+ "LINUX",
696
+ "MACOS",
697
+ "ANDROID"
698
+ ]
699
+ },
700
+ {
701
+ "key": "thread_safety",
702
+ "label": "Thread Safety",
703
+ "description": "Thread checks. In order to not degrade performance, it might be best to run your program with thread-checking disabled most of the time, enabling it occasionally for a quick sanity check or when debugging difficult application behaviors.",
704
+ "type": "BOOL",
705
+ "default": true,
706
+ "status": "STABLE",
707
+ "platforms": [
708
+ "WINDOWS",
709
+ "LINUX",
710
+ "MACOS",
711
+ "ANDROID"
712
+ ]
713
+ },
714
+ {
715
+ "key": "validate_sync",
716
+ "label": "Synchronization",
717
+ "description": "Enable synchronization validation during command buffers recording. This feature reports resource access conflicts due to missing or incorrect synchronization operations between actions (Draw, Copy, Dispatch, Blit) reading or writing the same regions of memory.",
718
+ "url": "${LUNARG_SDK}/synchronization_usage.html",
719
+ "type": "BOOL",
720
+ "default": false,
721
+ "expanded": true,
722
+ "status": "STABLE",
723
+ "platforms": [
724
+ "WINDOWS",
725
+ "LINUX",
726
+ "MACOS",
727
+ "ANDROID"
728
+ ],
729
+ "settings": [
730
+ {
731
+ "key": "sync_queue_submit",
732
+ "label": "QueueSubmit Synchronization Validation",
733
+ "description": "Enable synchronization validation between submitted command buffers when Synchronization Validation is enabled. This option will increase the synchronization performance cost.",
734
+ "type": "BOOL",
735
+ "default": true,
736
+ "status": "STABLE",
737
+ "dependence": {
738
+ "mode": "ALL",
739
+ "settings": [
740
+ {
741
+ "key": "validate_sync",
742
+ "value": true
743
+ }
744
+ ]
745
+ }
746
+ }
747
+ ]
748
+ },
749
+ {
750
+ "key": "validate_gpu_based",
751
+ "label": "GPU Base",
752
+ "description": "Setting an option here will enable specialized areas of validation",
753
+ "type": "ENUM",
754
+ "default": "GPU_BASED_NONE",
755
+ "expanded": true,
756
+ "status": "STABLE",
757
+ "platforms": [
758
+ "WINDOWS",
759
+ "LINUX"
760
+ ],
761
+ "flags": [
762
+ {
763
+ "key": "GPU_BASED_NONE",
764
+ "label": "None",
765
+ "description": "No GPU-based validation."
766
+ },
767
+ {
768
+ "key": "GPU_BASED_DEBUG_PRINTF",
769
+ "label": "Debug Printf",
770
+ "description": "Enables processing of debug printf instructions in shaders and sending debug strings to the debug callback.",
771
+ "url": "${LUNARG_SDK}/debug_printf.html",
772
+ "status": "STABLE",
773
+ "platforms": [
774
+ "WINDOWS",
775
+ "LINUX"
776
+ ],
777
+ "settings": [
778
+ {
779
+ "key": "printf_to_stdout",
780
+ "label": "Redirect Printf messages to stdout",
781
+ "description": "Enable redirection of Debug Printf messages from the debug callback to stdout",
782
+ "type": "BOOL",
783
+ "default": true,
784
+ "platforms": [
785
+ "WINDOWS",
786
+ "LINUX"
787
+ ],
788
+ "dependence": {
789
+ "mode": "ALL",
790
+ "settings": [
791
+ {
792
+ "key": "validate_gpu_based",
793
+ "value": "GPU_BASED_DEBUG_PRINTF"
794
+ }
795
+ ]
796
+ }
797
+ },
798
+ {
799
+ "key": "printf_verbose",
800
+ "label": "Printf verbose",
801
+ "description": "Set the verbosity of debug printf messages",
802
+ "type": "BOOL",
803
+ "default": false,
804
+ "platforms": [
805
+ "WINDOWS",
806
+ "LINUX"
807
+ ],
808
+ "dependence": {
809
+ "mode": "ALL",
810
+ "settings": [
811
+ {
812
+ "key": "validate_gpu_based",
813
+ "value": "GPU_BASED_DEBUG_PRINTF"
814
+ }
815
+ ]
816
+ }
817
+ },
818
+ {
819
+ "key": "printf_buffer_size",
820
+ "label": "Printf buffer size",
821
+ "description": "Set the size in bytes of the buffer used by debug printf",
822
+ "type": "INT",
823
+ "default": 1024,
824
+ "range": {
825
+ "min": 128,
826
+ "max": 1048576
827
+ },
828
+ "unit": "bytes",
829
+ "platforms": [
830
+ "WINDOWS",
831
+ "LINUX"
832
+ ],
833
+ "dependence": {
834
+ "mode": "ALL",
835
+ "settings": [
836
+ {
837
+ "key": "validate_gpu_based",
838
+ "value": "GPU_BASED_DEBUG_PRINTF"
839
+ }
840
+ ]
841
+ }
842
+ }
843
+ ]
844
+ },
845
+ {
846
+ "key": "GPU_BASED_GPU_ASSISTED",
847
+ "label": "GPU-Assisted",
848
+ "description": "Check for API usage errors at shader execution time.",
849
+ "url": "${LUNARG_SDK}/gpu_validation.html",
850
+ "platforms": [
851
+ "WINDOWS",
852
+ "LINUX"
853
+ ],
854
+ "settings": [
855
+ {
856
+ "key": "gpuav_shader_instrumentation",
857
+ "label": "Shader instrumentation",
858
+ "description": "Instrument shaders to validate descriptors, descriptor indexing, buffer device addresses and ray queries. Warning: will considerably slow down shader executions.",
859
+ "type": "BOOL",
860
+ "default": true,
861
+ "platforms": [
862
+ "WINDOWS",
863
+ "LINUX"
864
+ ],
865
+ "dependence": {
866
+ "mode": "ALL",
867
+ "settings": [
868
+ {
869
+ "key": "validate_gpu_based",
870
+ "value": "GPU_BASED_GPU_ASSISTED"
871
+ }
872
+ ]
873
+ },
874
+ "settings": [
875
+ {
876
+ "key": "gpuav_descriptor_checks",
877
+ "label": "Descriptors indexing",
878
+ "description": "Enable descriptors and buffer out of bounds validation when using descriptor indexing",
879
+ "type": "BOOL",
880
+ "default": true,
881
+ "platforms": [
882
+ "WINDOWS",
883
+ "LINUX"
884
+ ],
885
+ "dependence": {
886
+ "mode": "ALL",
887
+ "settings": [
888
+ {
889
+ "key": "gpuav_shader_instrumentation",
890
+ "value": true
891
+ }
892
+ ]
893
+ },
894
+ "settings": [
895
+ {
896
+ "key": "gpuav_warn_on_robust_oob",
897
+ "label": "Generate warning on out of bounds accesses even if buffer robustness is enabled",
898
+ "description": "Warn on out of bounds accesses even if robustness is enabled",
899
+ "type": "BOOL",
900
+ "default": true,
901
+ "platforms": [
902
+ "WINDOWS",
903
+ "LINUX"
904
+ ],
905
+ "dependence": {
906
+ "mode": "ALL",
907
+ "settings": [
908
+ {
909
+ "key": "gpuav_shader_instrumentation",
910
+ "value": true
911
+ }
912
+ ]
913
+ }
914
+ }
915
+ ]
916
+ },
917
+ {
918
+ "key": "gpuav_buffer_address_oob",
919
+ "label": "Out of bounds buffer device addresses",
920
+ "type": "BOOL",
921
+ "default": true,
922
+ "description": "Check for ",
923
+ "platforms": [
924
+ "WINDOWS",
925
+ "LINUX"
926
+ ],
927
+ "dependence": {
928
+ "mode": "ALL",
929
+ "settings": [
930
+ {
931
+ "key": "gpuav_shader_instrumentation",
932
+ "value": true
933
+ }
934
+ ]
935
+ },
936
+ "settings": [
937
+ {
938
+ "key": "gpuav_max_buffer_device_addresses",
939
+ "label": "Maximum number of buffer device addresses in use at one time",
940
+ "description": "",
941
+ "type": "INT",
942
+ "default": 10000,
943
+ "range": {
944
+ "min": 100,
945
+ "max": 10000000
946
+ },
947
+ "platforms": [
948
+ "WINDOWS",
949
+ "LINUX"
950
+ ],
951
+ "dependence": {
952
+ "mode": "ALL",
953
+ "settings": [
954
+ {
955
+ "key": "gpuav_shader_instrumentation",
956
+ "value": true
957
+ }
958
+ ]
959
+ }
960
+ }
961
+ ]
962
+ },
963
+ {
964
+ "key": "gpuav_validate_ray_query",
965
+ "label": "RayQuery SPIR-V Instructions",
966
+ "description": "Enable shader instrumentation on OpRayQueryInitializeKHR",
967
+ "type": "BOOL",
968
+ "default": true,
969
+ "platforms": [
970
+ "WINDOWS",
971
+ "LINUX"
972
+ ],
973
+ "dependence": {
974
+ "mode": "ALL",
975
+ "settings": [
976
+ {
977
+ "key": "gpuav_shader_instrumentation",
978
+ "value": true
979
+ }
980
+ ]
981
+ }
982
+ },
983
+ {
984
+ "key": "gpuav_cache_instrumented_shaders",
985
+ "label": "Cache instrumented shaders rather than instrumenting them on every run",
986
+ "description": "Enable instrumented shader caching",
987
+ "type": "BOOL",
988
+ "default": true,
989
+ "platforms": [
990
+ "WINDOWS",
991
+ "LINUX"
992
+ ],
993
+ "dependence": {
994
+ "mode": "ALL",
995
+ "settings": [
996
+ {
997
+ "key": "gpuav_shader_instrumentation",
998
+ "value": true
999
+ }
1000
+ ]
1001
+ }
1002
+ },
1003
+ {
1004
+ "key": "gpuav_select_instrumented_shaders",
1005
+ "label": "Enable instrumenting shaders selectively",
1006
+ "description": "Select which shaders to instrument passing a VkValidationFeaturesEXT struct with GPU-AV enabled in the VkShaderModuleCreateInfo pNext",
1007
+ "type": "BOOL",
1008
+ "default": false,
1009
+ "platforms": [
1010
+ "WINDOWS",
1011
+ "LINUX"
1012
+ ],
1013
+ "dependence": {
1014
+ "mode": "ALL",
1015
+ "settings": [
1016
+ {
1017
+ "key": "gpuav_shader_instrumentation",
1018
+ "value": true
1019
+ }
1020
+ ]
1021
+ }
1022
+ }
1023
+ ]
1024
+ },
1025
+ {
1026
+ "key": "gpuav_buffers_validation",
1027
+ "label": "Buffer content validation",
1028
+ "description": "Validate buffers containing parameters used in indirect Vulkan commands, or used in copy commands",
1029
+ "type": "BOOL",
1030
+ "default": true,
1031
+ "platforms": [
1032
+ "WINDOWS",
1033
+ "LINUX"
1034
+ ],
1035
+ "dependence": {
1036
+ "mode": "ALL",
1037
+ "settings": [
1038
+ {
1039
+ "key": "validate_gpu_based",
1040
+ "value": "GPU_BASED_GPU_ASSISTED"
1041
+ }
1042
+ ]
1043
+ },
1044
+ "settings": [
1045
+ {
1046
+ "key": "gpuav_indirect_draws_buffers",
1047
+ "label": "Indirect draws parameters",
1048
+ "type": "BOOL",
1049
+ "default": true,
1050
+ "description": "Validate buffers containing draw parameters used in indirect draw commands",
1051
+ "platforms": [
1052
+ "WINDOWS",
1053
+ "LINUX"
1054
+ ],
1055
+ "dependence": {
1056
+ "mode": "ALL",
1057
+ "settings": [
1058
+ {
1059
+ "key": "gpuav_buffers_validation",
1060
+ "value": true
1061
+ }
1062
+ ]
1063
+ }
1064
+ },
1065
+ {
1066
+ "key": "indirect_dispatches",
1067
+ "label": "Indirect dispatches parameters",
1068
+ "type": "BOOL",
1069
+ "default": true,
1070
+ "description": "Validate buffers containing dispatch parameters used in indirect dispatch commands",
1071
+ "platforms": [
1072
+ "WINDOWS",
1073
+ "LINUX"
1074
+ ],
1075
+ "dependence": {
1076
+ "mode": "ALL",
1077
+ "settings": [
1078
+ {
1079
+ "key": "gpuav_buffers_validation",
1080
+ "value": true
1081
+ }
1082
+ ]
1083
+ }
1084
+ },
1085
+ {
1086
+ "key": "indirect_trace_rays",
1087
+ "label": "Indirect trace rays parameters",
1088
+ "type": "BOOL",
1089
+ "default": true,
1090
+ "description": "Validate buffers containing ray tracing parameters used in indirect ray tracing commands",
1091
+ "platforms": [
1092
+ "WINDOWS",
1093
+ "LINUX"
1094
+ ],
1095
+ "dependence": {
1096
+ "mode": "ALL",
1097
+ "settings": [
1098
+ {
1099
+ "key": "gpuav_buffers_validation",
1100
+ "value": true
1101
+ }
1102
+ ]
1103
+ }
1104
+ },
1105
+ {
1106
+ "key": "gpuav_buffer_copies",
1107
+ "label": "Buffer copies",
1108
+ "type": "BOOL",
1109
+ "default": true,
1110
+ "description": "Validate copies involving a VkBuffer. Right now only validates copy buffer to image.",
1111
+ "platforms": [
1112
+ "WINDOWS",
1113
+ "LINUX"
1114
+ ],
1115
+ "dependence": {
1116
+ "mode": "ALL",
1117
+ "settings": [
1118
+ {
1119
+ "key": "gpuav_buffers_validation",
1120
+ "value": true
1121
+ }
1122
+ ]
1123
+ }
1124
+ }
1125
+ ]
1126
+ },
1127
+ {
1128
+ "key": "gpuav_advanced_settings",
1129
+ "label": "Advanced Settings",
1130
+ "description": "GPU-AV advanced settings",
1131
+ "type": "GROUP",
1132
+ "view": "ADVANCED",
1133
+ "platforms": [
1134
+ "WINDOWS",
1135
+ "LINUX"
1136
+ ],
1137
+ "dependence": {
1138
+ "mode": "ALL",
1139
+ "settings": [
1140
+ {
1141
+ "key": "validate_gpu_based",
1142
+ "value": "GPU_BASED_GPU_ASSISTED"
1143
+ }
1144
+ ]
1145
+ },
1146
+ "settings": [
1147
+ {
1148
+ "key": "gpuav_reserve_binding_slot",
1149
+ "label": "Reserve Descriptor Set Binding Slot",
1150
+ "type": "BOOL",
1151
+ "default": true,
1152
+ "description": "Specifies that the validation layers reserve a descriptor set binding slot for their own use. The layer reports a value for VkPhysicalDeviceLimits::maxBoundDescriptorSets that is one less than the value reported by the device. If the device supports the binding of only one descriptor set, the validation layer does not perform GPU-assisted validation.",
1153
+ "platforms": [
1154
+ "WINDOWS",
1155
+ "LINUX"
1156
+ ],
1157
+ "dependence": {
1158
+ "mode": "ALL",
1159
+ "settings": [
1160
+ {
1161
+ "key": "validate_gpu_based",
1162
+ "value": "GPU_BASED_GPU_ASSISTED"
1163
+ }
1164
+ ]
1165
+ }
1166
+ },
1167
+ {
1168
+ "key": "gpuav_vma_linear_output",
1169
+ "label": "Linear Memory Allocation Mode",
1170
+ "description": "Use VMA linear memory allocations for GPU-AV output buffers instead of finding best place for new allocations among free regions to optimize memory usage. Enabling this setting reduces performance cost but disabling this method minimizes memory usage.",
1171
+ "type": "BOOL",
1172
+ "default": true,
1173
+ "platforms": [
1174
+ "WINDOWS",
1175
+ "LINUX"
1176
+ ],
1177
+ "dependence": {
1178
+ "mode": "ALL",
1179
+ "settings": [
1180
+ {
1181
+ "key": "validate_gpu_based",
1182
+ "value": "GPU_BASED_GPU_ASSISTED"
1183
+ }
1184
+ ]
1185
+ }
1186
+ }
1187
+ ]
1188
+ },
1189
+ {
1190
+ "key": "gpuav_debug_settings",
1191
+ "label": "Developer Debug Settings",
1192
+ "description": "GPU-AV debug settings",
1193
+ "type": "GROUP",
1194
+ "view": "ADVANCED",
1195
+ "platforms": [
1196
+ "WINDOWS",
1197
+ "LINUX"
1198
+ ],
1199
+ "dependence": {
1200
+ "mode": "ALL",
1201
+ "settings": [
1202
+ {
1203
+ "key": "validate_gpu_based",
1204
+ "value": "GPU_BASED_GPU_ASSISTED"
1205
+ }
1206
+ ]
1207
+ },
1208
+ "settings": [
1209
+ {
1210
+ "key": "gpuav_debug_validate_instrumented_shaders",
1211
+ "label": "Validate instrumented shaders",
1212
+ "description": "Run spirv-val after doing shader instrumentation",
1213
+ "type": "BOOL",
1214
+ "default": false,
1215
+ "platforms": [
1216
+ "WINDOWS",
1217
+ "LINUX"
1218
+ ],
1219
+ "dependence": {
1220
+ "mode": "ALL",
1221
+ "settings": [
1222
+ {
1223
+ "key": "validate_gpu_based",
1224
+ "value": "GPU_BASED_GPU_ASSISTED"
1225
+ }
1226
+ ]
1227
+ }
1228
+ },
1229
+ {
1230
+ "key": "gpuav_debug_dump_instrumented_shaders",
1231
+ "label": "Dump instrumented shaders",
1232
+ "description": "Will dump the instrumented shaders (before and after) to working directory",
1233
+ "type": "BOOL",
1234
+ "default": false,
1235
+ "platforms": [
1236
+ "WINDOWS",
1237
+ "LINUX"
1238
+ ],
1239
+ "dependence": {
1240
+ "mode": "ALL",
1241
+ "settings": [
1242
+ {
1243
+ "key": "validate_gpu_based",
1244
+ "value": "GPU_BASED_GPU_ASSISTED"
1245
+ }
1246
+ ]
1247
+ }
1248
+ }
1249
+ ]
1250
+ }
1251
+ ]
1252
+ }
1253
+ ]
1254
+ },
1255
+ {
1256
+ "key": "validate_best_practices",
1257
+ "label": "Best Practices",
1258
+ "description": "Outputs warnings related to common misuse of the API, but which are not explicitly prohibited by the specification.",
1259
+ "url": "${LUNARG_SDK}/best_practices.html",
1260
+ "type": "BOOL",
1261
+ "default": false,
1262
+ "expanded": true,
1263
+ "status": "STABLE",
1264
+ "platforms": [
1265
+ "WINDOWS",
1266
+ "LINUX",
1267
+ "MACOS",
1268
+ "ANDROID"
1269
+ ],
1270
+ "settings": [
1271
+ {
1272
+ "key": "validate_best_practices_arm",
1273
+ "label": "ARM-specific best practices",
1274
+ "description": "Outputs warnings for spec-conforming but non-ideal code on ARM GPUs.",
1275
+ "type": "BOOL",
1276
+ "default": false,
1277
+ "platforms": [
1278
+ "WINDOWS",
1279
+ "LINUX",
1280
+ "MACOS",
1281
+ "ANDROID"
1282
+ ],
1283
+ "dependence": {
1284
+ "mode": "ALL",
1285
+ "settings": [
1286
+ {
1287
+ "key": "validate_best_practices",
1288
+ "value": true
1289
+ }
1290
+ ]
1291
+ }
1292
+ },
1293
+ {
1294
+ "key": "validate_best_practices_amd",
1295
+ "label": "AMD-specific best practices",
1296
+ "description": "Outputs warnings for spec-conforming but non-ideal code on AMD GPUs.",
1297
+ "type": "BOOL",
1298
+ "default": false,
1299
+ "platforms": [
1300
+ "WINDOWS",
1301
+ "LINUX",
1302
+ "MACOS"
1303
+ ],
1304
+ "dependence": {
1305
+ "mode": "ALL",
1306
+ "settings": [
1307
+ {
1308
+ "key": "validate_best_practices",
1309
+ "value": true
1310
+ }
1311
+ ]
1312
+ }
1313
+ },
1314
+ {
1315
+ "key": "validate_best_practices_img",
1316
+ "label": "IMG-specific best practices",
1317
+ "description": "Outputs warnings for spec-conforming but non-ideal code on Imagination GPUs.",
1318
+ "type": "BOOL",
1319
+ "default": false,
1320
+ "platforms": [
1321
+ "WINDOWS",
1322
+ "LINUX",
1323
+ "MACOS"
1324
+ ],
1325
+ "dependence": {
1326
+ "mode": "ALL",
1327
+ "settings": [
1328
+ {
1329
+ "key": "validate_best_practices",
1330
+ "value": true
1331
+ }
1332
+ ]
1333
+ }
1334
+ },
1335
+ {
1336
+ "key": "validate_best_practices_nvidia",
1337
+ "label": "NVIDIA-specific best practices",
1338
+ "description": "Outputs warnings for spec-conforming but non-ideal code on NVIDIA GPUs.",
1339
+ "type": "BOOL",
1340
+ "default": false,
1341
+ "platforms": [
1342
+ "WINDOWS",
1343
+ "LINUX",
1344
+ "ANDROID"
1345
+ ],
1346
+ "dependence": {
1347
+ "mode": "ALL",
1348
+ "settings": [
1349
+ {
1350
+ "key": "validate_best_practices",
1351
+ "value": true
1352
+ }
1353
+ ]
1354
+ }
1355
+ }
1356
+ ]
1357
+ }
1358
+ ]
1359
+ },
1360
+ {
1361
+ "key": "debug_action",
1362
+ "label": "Debug Action",
1363
+ "description": "Specifies what action is to be taken when a layer reports information",
1364
+ "type": "FLAGS",
1365
+ "flags": [
1366
+ {
1367
+ "key": "VK_DBG_LAYER_ACTION_LOG_MSG",
1368
+ "label": "Log Message",
1369
+ "description": "Log a txt message to stdout or to a log filename.",
1370
+ "settings": [
1371
+ {
1372
+ "key": "log_filename",
1373
+ "label": "Log Filename",
1374
+ "description": "Specifies the output filename",
1375
+ "type": "SAVE_FILE",
1376
+ "default": "stdout",
1377
+ "dependence": {
1378
+ "mode": "ALL",
1379
+ "settings": [
1380
+ {
1381
+ "key": "debug_action",
1382
+ "value": [
1383
+ "VK_DBG_LAYER_ACTION_LOG_MSG"
1384
+ ]
1385
+ }
1386
+ ]
1387
+ }
1388
+ }
1389
+ ]
1390
+ },
1391
+ {
1392
+ "key": "VK_DBG_LAYER_ACTION_CALLBACK",
1393
+ "label": "Callback",
1394
+ "description": "Call user defined callback function(s) that have been registered via the VK_EXT_debug_report extension. Since application must register callback, this is a NOOP for the settings file.",
1395
+ "view": "HIDDEN"
1396
+ },
1397
+ {
1398
+ "key": "VK_DBG_LAYER_ACTION_DEBUG_OUTPUT",
1399
+ "label": "Debug Output",
1400
+ "description": "Log a txt message using the Windows OutputDebugString function.",
1401
+ "platforms": [
1402
+ "WINDOWS"
1403
+ ]
1404
+ },
1405
+ {
1406
+ "key": "VK_DBG_LAYER_ACTION_BREAK",
1407
+ "label": "Break",
1408
+ "description": "Trigger a breakpoint if a debugger is in use."
1409
+ }
1410
+ ],
1411
+ "default": [
1412
+ "VK_DBG_LAYER_ACTION_LOG_MSG"
1413
+ ]
1414
+ },
1415
+ {
1416
+ "key": "report_flags",
1417
+ "label": "Message Severity",
1418
+ "description": "Comma-delineated list of options specifying the types of messages to be reported",
1419
+ "type": "FLAGS",
1420
+ "flags": [
1421
+ {
1422
+ "key": "info",
1423
+ "label": "Info",
1424
+ "description": "Report informational messages."
1425
+ },
1426
+ {
1427
+ "key": "warn",
1428
+ "label": "Warning",
1429
+ "description": "Report warnings from using the API in a manner which may lead to undefined behavior or to warn the user of common trouble spots. A warning does NOT necessarily signify illegal application behavior."
1430
+ },
1431
+ {
1432
+ "key": "perf",
1433
+ "label": "Performance",
1434
+ "description": "Report usage of the API that may cause suboptimal performance."
1435
+ },
1436
+ {
1437
+ "key": "error",
1438
+ "label": "Error",
1439
+ "description": "Report errors in API usage."
1440
+ },
1441
+ {
1442
+ "key": "debug",
1443
+ "label": "Debug",
1444
+ "description": "For layer development. Report messages for debugging layer behavior.",
1445
+ "view": "HIDDEN"
1446
+ }
1447
+ ],
1448
+ "default": [
1449
+ "error"
1450
+ ]
1451
+ },
1452
+ {
1453
+ "key": "enable_message_limit",
1454
+ "label": "Limit Duplicated Messages",
1455
+ "description": "Enable limiting of duplicate messages.",
1456
+ "type": "BOOL",
1457
+ "default": true,
1458
+ "settings": [
1459
+ {
1460
+ "key": "duplicate_message_limit",
1461
+ "env": "VK_LAYER_DUPLICATE_MESSAGE_LIMIT",
1462
+ "label": "Max Duplicated Messages",
1463
+ "description": "Maximum number of times any single validation message should be reported.",
1464
+ "type": "INT",
1465
+ "default": 10,
1466
+ "range": {
1467
+ "min": 1
1468
+ },
1469
+ "dependence": {
1470
+ "mode": "ALL",
1471
+ "settings": [
1472
+ {
1473
+ "key": "enable_message_limit",
1474
+ "value": true
1475
+ }
1476
+ ]
1477
+ }
1478
+ }
1479
+ ]
1480
+ },
1481
+ {
1482
+ "key": "message_id_filter",
1483
+ "label": "Mute Message VUIDs",
1484
+ "description": "List of VUIDs and VUID identifers which are to be IGNORED by the validation layer",
1485
+ "type": "LIST",
1486
+ "env": "VK_LAYER_MESSAGE_ID_FILTER",
1487
+ "default": []
1488
+ },
1489
+ {
1490
+ "key": "message_format",
1491
+ "label": "Message Format",
1492
+ "description": "Specifies how error messages are reported",
1493
+ "type": "GROUP",
1494
+ "expanded": true,
1495
+ "settings": [
1496
+ {
1497
+ "key": "message_format_display_application_name",
1498
+ "label": "Display Application Name",
1499
+ "description": "Useful when running multiple instances to know which instance the message is from.",
1500
+ "type": "BOOL",
1501
+ "default": false,
1502
+ "platforms": [
1503
+ "WINDOWS",
1504
+ "LINUX",
1505
+ "MACOS",
1506
+ "ANDROID"
1507
+ ]
1508
+ }
1509
+ ]
1510
+ },
1511
+ {
1512
+ "key": "disables",
1513
+ "label": "Disables",
1514
+ "description": "Specify areas of validation to be disabled",
1515
+ "type": "FLAGS",
1516
+ "env": "VK_LAYER_DISABLES",
1517
+ "flags": [
1518
+ {
1519
+ "key": "VK_VALIDATION_FEATURE_DISABLE_THREAD_SAFETY_EXT",
1520
+ "label": "Thread Safety",
1521
+ "description": "Thread checks. In order to not degrade performance, it might be best to run your program with thread-checking disabled most of the time, enabling it occasionally for a quick sanity check or when debugging difficult application behaviors."
1522
+ },
1523
+ {
1524
+ "key": "VK_VALIDATION_FEATURE_DISABLE_API_PARAMETERS_EXT",
1525
+ "label": "Stateless Parameter",
1526
+ "description": "Stateless parameter checks. This may not always be necessary late in a development cycle."
1527
+ },
1528
+ {
1529
+ "key": "VK_VALIDATION_FEATURE_DISABLE_OBJECT_LIFETIMES_EXT",
1530
+ "label": "Object Lifetime",
1531
+ "description": "Object tracking checks. This may not always be necessary late in a development cycle."
1532
+ },
1533
+ {
1534
+ "key": "VK_VALIDATION_FEATURE_DISABLE_CORE_CHECKS_EXT",
1535
+ "label": "Core",
1536
+ "description": "The main, heavy-duty validation checks. This may be valuable early in the development cycle to reduce validation output while correcting parameter/object usage errors."
1537
+ },
1538
+ {
1539
+ "key": "VK_VALIDATION_FEATURE_DISABLE_UNIQUE_HANDLES_EXT",
1540
+ "label": "Handle Wrapping",
1541
+ "description": "Handle wrapping checks. Disable this feature if you are exerience crashes when creating new extensions or developing new Vulkan objects/structures."
1542
+ },
1543
+ {
1544
+ "key": "VK_VALIDATION_FEATURE_DISABLE_SHADERS_EXT",
1545
+ "label": "Shader Validation",
1546
+ "description": "Shader checks. These checks can be CPU intensive during application start up, especially if Shader Validation Caching is also disabled.",
1547
+ "view": "ADVANCED"
1548
+ },
1549
+ {
1550
+ "key": "VALIDATION_CHECK_DISABLE_COMMAND_BUFFER_STATE",
1551
+ "label": "Command Buffer State",
1552
+ "description": "Check that all Vulkan objects used by a command buffer have not been destroyed. These checks can be CPU intensive for some applications.",
1553
+ "view": "ADVANCED"
1554
+ },
1555
+ {
1556
+ "key": "VALIDATION_CHECK_DISABLE_IMAGE_LAYOUT_VALIDATION",
1557
+ "label": "Image Layout",
1558
+ "description": "Check that the layout of each image subresource is correct whenever it is used by a command buffer. These checks are very CPU intensive for some applications.",
1559
+ "view": "ADVANCED"
1560
+ },
1561
+ {
1562
+ "key": "VALIDATION_CHECK_DISABLE_QUERY_VALIDATION",
1563
+ "label": "Query",
1564
+ "description": "Checks for commands that use VkQueryPool objects.",
1565
+ "view": "ADVANCED"
1566
+ },
1567
+ {
1568
+ "key": "VALIDATION_CHECK_DISABLE_OBJECT_IN_USE",
1569
+ "label": "Object in Use",
1570
+ "description": "Check that Vulkan objects are not in use by a command buffer when they are destroyed.",
1571
+ "view": "ADVANCED"
1572
+ },
1573
+ {
1574
+ "key": "VALIDATION_CHECK_DISABLE_SYNCHRONIZATION_VALIDATION_QUEUE_SUBMIT",
1575
+ "label": "QueueSubmit Synchronization Validation",
1576
+ "description": "Check synchronization validation between submitted command buffers when Synchronization Validation is enabled.",
1577
+ "view": "ADVANCED"
1578
+ },
1579
+ {
1580
+ "key": "VK_VALIDATION_FEATURE_DISABLE_SHADER_VALIDATION_CACHE_EXT",
1581
+ "label": "Shader Validation Caching",
1582
+ "description": "Disable caching of shader validation results.",
1583
+ "view": "ADVANCED"
1584
+ }
1585
+ ],
1586
+ "default": [
1587
+ "VK_VALIDATION_FEATURE_DISABLE_THREAD_SAFETY_EXT"
1588
+ ]
1589
+ },
1590
+ {
1591
+ "key": "enables",
1592
+ "label": "Enables",
1593
+ "description": "Setting an option here will enable specialized areas of validation",
1594
+ "type": "FLAGS",
1595
+ "env": "VK_LAYER_ENABLES",
1596
+ "flags": [
1597
+ {
1598
+ "key": "VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT",
1599
+ "label": "Synchronization",
1600
+ "description": "This feature reports resource access conflicts due to missing or incorrect synchronization operations between actions (Draw, Copy, Dispatch, Blit) reading or writing the same regions of memory.",
1601
+ "url": "${LUNARG_SDK}/synchronization_usage.html",
1602
+ "status": "STABLE",
1603
+ "platforms": [
1604
+ "WINDOWS",
1605
+ "LINUX",
1606
+ "MACOS",
1607
+ "ANDROID"
1608
+ ]
1609
+ },
1610
+ {
1611
+ "key": "VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT",
1612
+ "label": "Debug Printf",
1613
+ "description": "Enables processing of debug printf instructions in shaders and sending debug strings to the debug callback.",
1614
+ "url": "${LUNARG_SDK}/debug_printf.html",
1615
+ "status": "STABLE",
1616
+ "platforms": [
1617
+ "WINDOWS",
1618
+ "LINUX"
1619
+ ]
1620
+ },
1621
+ {
1622
+ "key": "VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT",
1623
+ "label": "GPU-Assisted",
1624
+ "description": "Check for API usage errors at shader execution time.",
1625
+ "url": "${LUNARG_SDK}/gpu_validation.html",
1626
+ "platforms": [
1627
+ "WINDOWS",
1628
+ "LINUX"
1629
+ ]
1630
+ },
1631
+ {
1632
+ "key": "VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT",
1633
+ "label": "Reserve Descriptor Set Binding Slot",
1634
+ "description": "Specifies that the validation layers reserve a descriptor set binding slot for their own use. The layer reports a value for VkPhysicalDeviceLimits::maxBoundDescriptorSets that is one less than the value reported by the device. If the device supports the binding of only one descriptor set, the validation layer does not perform GPU-assisted validation.",
1635
+ "platforms": [
1636
+ "WINDOWS",
1637
+ "LINUX"
1638
+ ]
1639
+ },
1640
+ {
1641
+ "key": "VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT",
1642
+ "label": "Best Practices",
1643
+ "description": "Activating this feature enables the output of warnings related to common misuse of the API, but which are not explicitly prohibited by the specification.",
1644
+ "url": "${LUNARG_SDK}/best_practices.html",
1645
+ "platforms": [
1646
+ "WINDOWS",
1647
+ "LINUX",
1648
+ "MACOS",
1649
+ "ANDROID"
1650
+ ]
1651
+ },
1652
+ {
1653
+ "key": "VALIDATION_CHECK_ENABLE_VENDOR_SPECIFIC_ARM",
1654
+ "label": "ARM-specific best practices",
1655
+ "description": "Activating this feature enables the output of warnings related to ARM-specific misuse of the API, but which are not explicitly prohibited by the specification.",
1656
+ "platforms": [
1657
+ "WINDOWS",
1658
+ "LINUX",
1659
+ "MACOS",
1660
+ "ANDROID"
1661
+ ]
1662
+ },
1663
+ {
1664
+ "key": "VALIDATION_CHECK_ENABLE_VENDOR_SPECIFIC_AMD",
1665
+ "label": "AMD-specific best practices",
1666
+ "description": "Adds check for spec-conforming but non-ideal code on AMD GPUs.",
1667
+ "platforms": [
1668
+ "WINDOWS",
1669
+ "LINUX",
1670
+ "MACOS"
1671
+ ]
1672
+ },
1673
+ {
1674
+ "key": "VALIDATION_CHECK_ENABLE_VENDOR_SPECIFIC_IMG",
1675
+ "label": "IMG-specific best practices",
1676
+ "description": "Adds check for spec-conforming but non-ideal code on Imagination GPUs.",
1677
+ "platforms": [
1678
+ "WINDOWS",
1679
+ "LINUX",
1680
+ "MACOS"
1681
+ ]
1682
+ },
1683
+ {
1684
+ "key": "VALIDATION_CHECK_ENABLE_VENDOR_SPECIFIC_NVIDIA",
1685
+ "label": "NVIDIA-specific best practices",
1686
+ "description": "Activating this feature enables the output of warnings related to NVIDIA-specific misuse of the API, but which are not explicitly prohibited by the specification.",
1687
+ "platforms": [
1688
+ "WINDOWS",
1689
+ "LINUX",
1690
+ "ANDROID"
1691
+ ]
1692
+ },
1693
+ {
1694
+ "key": "VALIDATION_CHECK_ENABLE_VENDOR_SPECIFIC_ALL",
1695
+ "label": "Hardware specific best practices",
1696
+ "description": "Activating this feature enables all vendor specific best practices.",
1697
+ "platforms": [
1698
+ "WINDOWS",
1699
+ "LINUX",
1700
+ "ANDROID"
1701
+ ]
1702
+ }
1703
+ ],
1704
+ "default": []
1705
+ }
1706
+ ]
1707
+ }
1708
+ }
1709
+ }
third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/mac/vulkan/icd.d/MoltenVK_icd.json ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "file_format_version": "1.0.0",
3
+ "ICD": {
4
+ "library_path": "../../../Frameworks/libMoltenVK.dylib",
5
+ "api_version": "1.2.0",
6
+ "is_portability_driver": true
7
+ }
8
+ }
third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/shaders/textoverlay.frag ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2017-2020 Mark Callow
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ #version 450 core
5
+
6
+ layout (location = 0) in vec2 inUV;
7
+
8
+ layout (binding = 0) uniform sampler2D samplerFont;
9
+
10
+ layout (location = 0) out vec4 outFragColor;
11
+
12
+ void main(void)
13
+ {
14
+ float color = texture(samplerFont, inUV).r;
15
+ outFragColor = vec4(vec3(color), 1.0);
16
+ }
third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/shaders/textoverlay.vert ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2017-2020 Mark Callow
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ #version 450 core
5
+
6
+ layout (location = 0) in vec2 inPos;
7
+ layout (location = 1) in vec2 inUV;
8
+
9
+ layout (location = 0) out vec2 outUV;
10
+
11
+ out gl_PerVertex
12
+ {
13
+ vec4 gl_Position;
14
+ };
15
+
16
+ void main(void)
17
+ {
18
+ gl_Position = vec4(inPos, 0.0, 1.0);
19
+ outUV = inUV;
20
+ }
third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/vulkancheckres.h ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* -*- tab-width: 4; -*- */
2
+ /* vi: set sw=2 ts=4 expandtab: */
3
+
4
+ #ifndef VULKAN_CHECK_RES_H_1456211188
5
+ #define VULKAN_CHECK_RES_H_1456211188
6
+
7
+ /*
8
+ * Copyright 2017-2020 Mark Callow.
9
+ * SPDX-License-Identifier: Apache-2.0
10
+ */
11
+
12
+ #include <stdio.h>
13
+ #include <string.h>
14
+ #include <iomanip>
15
+ #include <sstream>
16
+
17
+ #include <SDL3/SDL_messagebox.h>
18
+
19
+ /**
20
+ * @internal
21
+ * @file
22
+ * @~English
23
+ *
24
+ * @brief Check result of a Vulkan command.
25
+ *
26
+ * Use for commands that will always succeed unless usage is invalid.
27
+ */
28
+ #if defined(DEBUG)
29
+ #define VK_CHECK_RESULT(f) \
30
+ { \
31
+ VkResult res = (f); \
32
+ if (res != VK_SUCCESS) \
33
+ { \
34
+ std::stringstream msg; \
35
+ msg << "Fatal : VkResult is \"" << res << "\" in " << __FILE__ \
36
+ << " at line " << __LINE__ << std::endl; \
37
+ SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, \
38
+ "VkSample_02_cube_textured", \
39
+ msg.str().c_str(), \
40
+ NULL); \
41
+ assert(res == VK_SUCCESS); \
42
+ } \
43
+ }
44
+ #else
45
+ #define VK_CHECK_RESULT(f) (void)f
46
+ #endif
47
+
48
+ #endif
third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/vulkandebug.cpp ADDED
@@ -0,0 +1,288 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Vulkan examples debug wrapper
3
+ *
4
+ * Appendix for VK_EXT_Debug_Report can be found at https://github.com/KhronosGroup/Vulkan-Docs/blob/1.0-VK_EXT_debug_report/doc/specs/vulkan/appendices/debug_report.txt
5
+ *
6
+ * Copyright 2016 Sascha Willems - www.saschawillems.de
7
+ * SPDX-License-Identifier: MIT
8
+ */
9
+
10
+ #include "vulkandebug.h"
11
+ #include <iostream>
12
+ #include "unused.h"
13
+
14
+ namespace vkDebug
15
+ {
16
+ int validationLayerCount = 1;
17
+ const char *validationLayerNames[] =
18
+ {
19
+ // This is a meta layer that enables all of the standard
20
+ // validation layers in the correct order :
21
+ // threading, parameter_validation, device_limits, object_tracker, image, core_validation, swapchain, and unique_objects
22
+ "VK_LAYER_LUNARG_standard_validation"
23
+ };
24
+
25
+ PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallback = VK_NULL_HANDLE;
26
+ PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallback = VK_NULL_HANDLE;
27
+ PFN_vkDebugReportMessageEXT dbgBreakCallback = VK_NULL_HANDLE;
28
+
29
+ VkDebugReportCallbackEXT msgCallback;
30
+
31
+ VkBool32 messageCallback(
32
+ VkDebugReportFlagsEXT flags,
33
+ VkDebugReportObjectTypeEXT /*objType*/,
34
+ uint64_t /*srcObject*/,
35
+ size_t /*location*/,
36
+ int32_t msgCode,
37
+ const char* pLayerPrefix,
38
+ const char* pMsg,
39
+ void* /*pUserData*/)
40
+ {
41
+ // Message text passed in by validation layer
42
+ std::string text(pMsg);
43
+
44
+ // Select prefix depending on flags passed to the callback
45
+ // Note that multiple flags may be set for a single validation message
46
+ std::string prefix("");
47
+
48
+ // Error that may result in undefined behaviour
49
+ if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT)
50
+ {
51
+ prefix += "ERROR:";
52
+ };
53
+ // Warnings may hint at unexpected / non-spec API usage
54
+ if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT)
55
+ {
56
+ prefix += "WARNING:";
57
+ };
58
+ // May indicate sub-optimal usage of the API
59
+ if (flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT)
60
+ {
61
+ prefix += "PERFORMANCE:";
62
+ };
63
+ // Informal messages that may become handy during debugging
64
+ if (flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT)
65
+ {
66
+ prefix += "INFO:";
67
+ }
68
+ // Diagnostic info from the Vulkan loader and layers
69
+ // Usually not helpful in terms of API usage, but may help to debug layer and loader problems
70
+ if (flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT)
71
+ {
72
+ prefix += "DEBUG:";
73
+ }
74
+
75
+ // Display message to default output (console if activated)
76
+ std::cout << prefix << " [" << pLayerPrefix << "] Code " << msgCode << " : " << pMsg << "\n";
77
+
78
+ fflush(stdout);
79
+
80
+ // The return value of this callback controls wether the Vulkan call that caused
81
+ // the validation message will be aborted or not
82
+ // We return VK_FALSE as we DON'T want Vulkan calls that cause a validation message
83
+ // (and return a VkResult) to abort
84
+ // If you instead want to have calls abort, pass in VK_TRUE and the function will
85
+ // return VK_ERROR_VALIDATION_FAILED_EXT
86
+ return VK_FALSE;
87
+ }
88
+
89
+ void setupDebugging(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportCallbackEXT callBack)
90
+ {
91
+ CreateDebugReportCallback = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT");
92
+ DestroyDebugReportCallback = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT");
93
+ dbgBreakCallback = (PFN_vkDebugReportMessageEXT)vkGetInstanceProcAddr(instance, "vkDebugReportMessageEXT");
94
+
95
+ VkDebugReportCallbackCreateInfoEXT dbgCreateInfo = {};
96
+ dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
97
+ dbgCreateInfo.pfnCallback = (PFN_vkDebugReportCallbackEXT)messageCallback;
98
+ dbgCreateInfo.flags = flags;
99
+
100
+ U_ASSERT_ONLY VkResult err = CreateDebugReportCallback(
101
+ instance,
102
+ &dbgCreateInfo,
103
+ nullptr,
104
+ (callBack != VK_NULL_HANDLE) ? &callBack : &msgCallback);
105
+ assert(!err);
106
+ (void)err; // Supress VC++ unused variable warning for Release config.
107
+ }
108
+
109
+ void freeDebugCallback(VkInstance instance)
110
+ {
111
+ if (msgCallback != VK_NULL_HANDLE)
112
+ {
113
+ DestroyDebugReportCallback(instance, msgCallback, nullptr);
114
+ }
115
+ }
116
+
117
+ namespace DebugMarker
118
+ {
119
+ bool active = false;
120
+
121
+ PFN_vkDebugMarkerSetObjectTagEXT pfnDebugMarkerSetObjectTag = VK_NULL_HANDLE;
122
+ PFN_vkDebugMarkerSetObjectNameEXT pfnDebugMarkerSetObjectName = VK_NULL_HANDLE;
123
+ PFN_vkCmdDebugMarkerBeginEXT pfnCmdDebugMarkerBegin = VK_NULL_HANDLE;
124
+ PFN_vkCmdDebugMarkerEndEXT pfnCmdDebugMarkerEnd = VK_NULL_HANDLE;
125
+ PFN_vkCmdDebugMarkerInsertEXT pfnCmdDebugMarkerInsert = VK_NULL_HANDLE;
126
+
127
+ void setup(VkDevice device)
128
+ {
129
+ pfnDebugMarkerSetObjectTag = (PFN_vkDebugMarkerSetObjectTagEXT)vkGetDeviceProcAddr(device, "vkDebugMarkerSetObjectTagEXT");
130
+ pfnDebugMarkerSetObjectName = (PFN_vkDebugMarkerSetObjectNameEXT)vkGetDeviceProcAddr(device, "vkDebugMarkerSetObjectNameEXT");
131
+ pfnCmdDebugMarkerBegin = (PFN_vkCmdDebugMarkerBeginEXT)vkGetDeviceProcAddr(device, "vkCmdDebugMarkerBeginEXT");
132
+ pfnCmdDebugMarkerEnd = (PFN_vkCmdDebugMarkerEndEXT)vkGetDeviceProcAddr(device, "vkCmdDebugMarkerEndEXT");
133
+ pfnCmdDebugMarkerInsert = (PFN_vkCmdDebugMarkerInsertEXT)vkGetDeviceProcAddr(device, "vkCmdDebugMarkerInsertEXT");
134
+
135
+ // Set flag if at least one function pointer is present
136
+ active = (pfnDebugMarkerSetObjectName != VK_NULL_HANDLE);
137
+ }
138
+
139
+ void setObjectName(VkDevice device, uint64_t object, VkDebugReportObjectTypeEXT objectType, const char *name)
140
+ {
141
+ // Check for valid function pointer (may not be present if not running in a debugging application)
142
+ if (pfnDebugMarkerSetObjectName)
143
+ {
144
+ VkDebugMarkerObjectNameInfoEXT nameInfo = {};
145
+ nameInfo.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT;
146
+ nameInfo.objectType = objectType;
147
+ nameInfo.object = object;
148
+ nameInfo.pObjectName = name;
149
+ pfnDebugMarkerSetObjectName(device, &nameInfo);
150
+ }
151
+ }
152
+
153
+ void setObjectTag(VkDevice device, uint64_t object, VkDebugReportObjectTypeEXT objectType, uint64_t name, size_t tagSize, const void* tag)
154
+ {
155
+ // Check for valid function pointer (may not be present if not running in a debugging application)
156
+ if (pfnDebugMarkerSetObjectTag)
157
+ {
158
+ VkDebugMarkerObjectTagInfoEXT tagInfo = {};
159
+ tagInfo.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_TAG_INFO_EXT;
160
+ tagInfo.objectType = objectType;
161
+ tagInfo.object = object;
162
+ tagInfo.tagName = name;
163
+ tagInfo.tagSize = tagSize;
164
+ tagInfo.pTag = tag;
165
+ pfnDebugMarkerSetObjectTag(device, &tagInfo);
166
+ }
167
+ }
168
+
169
+ void beginRegion(VkCommandBuffer cmdbuffer, const char* pMarkerName, glm::vec4 color)
170
+ {
171
+ // Check for valid function pointer (may not be present if not running in a debugging application)
172
+ if (pfnCmdDebugMarkerBegin)
173
+ {
174
+ VkDebugMarkerMarkerInfoEXT markerInfo = {};
175
+ markerInfo.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT;
176
+ memcpy(markerInfo.color, &color[0], sizeof(float) * 4);
177
+ markerInfo.pMarkerName = pMarkerName;
178
+ pfnCmdDebugMarkerBegin(cmdbuffer, &markerInfo);
179
+ }
180
+ }
181
+
182
+ void insert(VkCommandBuffer cmdbuffer, std::string markerName, glm::vec4 color)
183
+ {
184
+ // Check for valid function pointer (may not be present if not running in a debugging application)
185
+ if (pfnCmdDebugMarkerInsert)
186
+ {
187
+ VkDebugMarkerMarkerInfoEXT markerInfo = {};
188
+ markerInfo.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT;
189
+ memcpy(markerInfo.color, &color[0], sizeof(float) * 4);
190
+ markerInfo.pMarkerName = markerName.c_str();
191
+ pfnCmdDebugMarkerInsert(cmdbuffer, &markerInfo);
192
+ }
193
+ }
194
+
195
+ void endRegion(VkCommandBuffer cmdBuffer)
196
+ {
197
+ // Check for valid function (may not be present if not runnin in a debugging application)
198
+ if (pfnCmdDebugMarkerEnd)
199
+ {
200
+ pfnCmdDebugMarkerEnd(cmdBuffer);
201
+ }
202
+ }
203
+
204
+ void setCommandBufferName(VkDevice device, VkCommandBuffer cmdBuffer, const char * name)
205
+ {
206
+ setObjectName(device, (uint64_t)cmdBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, name);
207
+ }
208
+
209
+ void setQueueName(VkDevice device, VkQueue queue, const char * name)
210
+ {
211
+ setObjectName(device, (uint64_t)queue, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT, name);
212
+ }
213
+
214
+ void setImageName(VkDevice device, VkImage image, const char * name)
215
+ {
216
+ setObjectName(device, (uint64_t)image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, name);
217
+ }
218
+
219
+ void setSamplerName(VkDevice device, VkSampler sampler, const char * name)
220
+ {
221
+ setObjectName(device, (uint64_t)sampler, VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT, name);
222
+ }
223
+
224
+ void setBufferName(VkDevice device, VkBuffer buffer, const char * name)
225
+ {
226
+ setObjectName(device, (uint64_t)buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, name);
227
+ }
228
+
229
+ void setDeviceMemoryName(VkDevice device, VkDeviceMemory memory, const char * name)
230
+ {
231
+ setObjectName(device, (uint64_t)memory, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, name);
232
+ }
233
+
234
+ void setShaderModuleName(VkDevice device, VkShaderModule shaderModule, const char * name)
235
+ {
236
+ setObjectName(device, (uint64_t)shaderModule, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, name);
237
+ }
238
+
239
+ void setPipelineName(VkDevice device, VkPipeline pipeline, const char * name)
240
+ {
241
+ setObjectName(device, (uint64_t)pipeline, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, name);
242
+ }
243
+
244
+ void setPipelineLayoutName(VkDevice device, VkPipelineLayout pipelineLayout, const char * name)
245
+ {
246
+ setObjectName(device, (uint64_t)pipelineLayout, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT, name);
247
+ }
248
+
249
+ void setRenderPassName(VkDevice device, VkRenderPass renderPass, const char * name)
250
+ {
251
+ setObjectName(device, (uint64_t)renderPass, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, name);
252
+ }
253
+
254
+ void setFramebufferName(VkDevice device, VkFramebuffer framebuffer, const char * name)
255
+ {
256
+ setObjectName(device, (uint64_t)framebuffer, VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT, name);
257
+ }
258
+
259
+ void setDescriptorSetLayoutName(VkDevice device, VkDescriptorSetLayout descriptorSetLayout, const char * name)
260
+ {
261
+ setObjectName(device, (uint64_t)descriptorSetLayout, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT, name);
262
+ }
263
+
264
+ void setDescriptorSetName(VkDevice device, VkDescriptorSet descriptorSet, const char * name)
265
+ {
266
+ setObjectName(device, (uint64_t)descriptorSet, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, name);
267
+ }
268
+
269
+ void setSemaphoreName(VkDevice device, VkSemaphore semaphore, const char * name)
270
+ {
271
+ setObjectName(device, (uint64_t)semaphore, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, name);
272
+ }
273
+
274
+ void setFenceName(VkDevice device, VkFence fence, const char * name)
275
+ {
276
+ setObjectName(device, (uint64_t)fence, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, name);
277
+ }
278
+
279
+ void setEventName(VkDevice device, VkEvent _event, const char * name)
280
+ {
281
+ setObjectName(device, (uint64_t)_event, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, name);
282
+ }
283
+ }
284
+
285
+ }
286
+
287
+ // vi: set sw=2 ts=4 expandtab:
288
+
third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/vulkandebug.h ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright 2017-2020 Mark Callow
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ #pragma once
7
+ #include "vulkan/vulkan.h"
8
+
9
+ #include <math.h>
10
+ #include <stdlib.h>
11
+ #include <string>
12
+ #include <cstring>
13
+ #include <fstream>
14
+ #include <assert.h>
15
+ #include <stdio.h>
16
+ #include <vector>
17
+ #ifdef _WIN32
18
+ #include <windows.h>
19
+ #include <fcntl.h>
20
+ #include <io.h>
21
+ #endif
22
+
23
+ #define GLM_FORCE_RADIANS
24
+ #define GLM_FORCE_DEPTH_ZERO_TO_ONE
25
+ #include "disable_glm_warnings.h"
26
+ #include <glm/glm.hpp>
27
+ #include "reenable_warnings.h"
28
+
29
+ namespace vkDebug
30
+ {
31
+ // Default validation layers
32
+ extern int validationLayerCount;
33
+ extern const char *validationLayerNames[];
34
+
35
+ // Default debug callback
36
+ VkBool32 messageCallback(
37
+ VkDebugReportFlagsEXT flags,
38
+ VkDebugReportObjectTypeEXT objType,
39
+ uint64_t srcObject,
40
+ size_t location,
41
+ int32_t msgCode,
42
+ const char* pLayerPrefix,
43
+ const char* pMsg,
44
+ void* pUserData);
45
+
46
+ // Load debug function pointers and set debug callback
47
+ // if callBack is NULL, default message callback will be used
48
+ void setupDebugging(
49
+ VkInstance instance,
50
+ VkDebugReportFlagsEXT flags,
51
+ VkDebugReportCallbackEXT callBack);
52
+ // Clear debug callback
53
+ void freeDebugCallback(VkInstance instance);
54
+
55
+ // Setup and functions for the VK_EXT_debug_marker_extension
56
+ // Extension spec can be found at https://github.com/KhronosGroup/Vulkan-Docs/blob/1.0-VK_EXT_debug_marker/doc/specs/vulkan/appendices/VK_EXT_debug_marker.txt
57
+ // Note that the extension will only be present if run from an offline debugging application
58
+ // The actual check for extension presence and enabling it on the device is done in the example base class
59
+ // See VulkanExampleBase::createInstance and VulkanExampleBase::createDevice (base/vulkanexamplebase.cpp)
60
+ namespace DebugMarker
61
+ {
62
+ // Set to true if function pointer for the debug marker are available
63
+ extern bool active;
64
+
65
+ // Get function pointers for the debug report extensions from the device
66
+ void setup(VkDevice device);
67
+
68
+ // Sets the debug name of an object
69
+ // All Objects in Vulkan are represented by their 64-bit handles which are passed into this function
70
+ // along with the object type
71
+ void setObjectName(VkDevice device, uint64_t object, VkDebugReportObjectTypeEXT objectType, const char *name);
72
+
73
+ // Set the tag for an object
74
+ void setObjectTag(VkDevice device, uint64_t object, VkDebugReportObjectTypeEXT objectType, uint64_t name, size_t tagSize, const void* tag);
75
+
76
+ // Start a new debug marker region
77
+ void beginRegion(VkCommandBuffer cmdbuffer, const char* pMarkerName, glm::vec4 color);
78
+
79
+ // Insert a new debug marker into the command buffer
80
+ void insert(VkCommandBuffer cmdbuffer, std::string markerName, glm::vec4 color);
81
+
82
+ // End the current debug marker region
83
+ void endRegion(VkCommandBuffer cmdBuffer);
84
+
85
+ // Object specific naming functions
86
+ void setCommandBufferName(VkDevice device, VkCommandBuffer cmdBuffer, const char * name);
87
+ void setQueueName(VkDevice device, VkQueue queue, const char * name);
88
+ void setImageName(VkDevice device, VkImage image, const char * name);
89
+ void setSamplerName(VkDevice device, VkSampler sampler, const char * name);
90
+ void setBufferName(VkDevice device, VkBuffer buffer, const char * name);
91
+ void setDeviceMemoryName(VkDevice device, VkDeviceMemory memory, const char * name);
92
+ void setShaderModuleName(VkDevice device, VkShaderModule shaderModule, const char * name);
93
+ void setPipelineName(VkDevice device, VkPipeline pipeline, const char * name);
94
+ void setPipelineLayoutName(VkDevice device, VkPipelineLayout pipelineLayout, const char * name);
95
+ void setRenderPassName(VkDevice device, VkRenderPass renderPass, const char * name);
96
+ void setFramebufferName(VkDevice device, VkFramebuffer framebuffer, const char * name);
97
+ void setDescriptorSetLayoutName(VkDevice device, VkDescriptorSetLayout descriptorSetLayout, const char * name);
98
+ void setDescriptorSetName(VkDevice device, VkDescriptorSet descriptorSet, const char * name);
99
+ void setSemaphoreName(VkDevice device, VkSemaphore semaphore, const char * name);
100
+ void setFenceName(VkDevice device, VkFence fence, const char * name);
101
+ void setEventName(VkDevice device, VkEvent _event, const char * name);
102
+ }
103
+
104
+ }
105
+
106
+ // vi: set sw=2 ts=4 expandtab:
third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/vulkantextoverlay.hpp ADDED
@@ -0,0 +1,839 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright 2016 Sascha Willems - www.saschawillems.de
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * Text overlay class for displaying debug information
6
+ *
7
+ */
8
+
9
+ #pragma once
10
+
11
+ #include <stdio.h>
12
+ #include <stdlib.h>
13
+ #include <string.h>
14
+ #include <assert.h>
15
+ #include <vector>
16
+ #include <sstream>
17
+ #include <iomanip>
18
+
19
+ #include <vulkan/vulkan.h>
20
+ #include "vulkantools.h"
21
+ #include "vulkandebug.h"
22
+
23
+ #include "stb/stb_font_consolas_24_latin1.inl"
24
+
25
+ // Defines for the STB font used
26
+ // STB font files can be found at http://nothings.org/stb/font/
27
+ #define STB_FONT_NAME stb_font_consolas_24_latin1
28
+ #define STB_FONT_WIDTH STB_FONT_consolas_24_latin1_BITMAP_WIDTH
29
+ #define STB_FONT_HEIGHT STB_FONT_consolas_24_latin1_BITMAP_HEIGHT
30
+ #define STB_FIRST_CHAR STB_FONT_consolas_24_latin1_FIRST_CHAR
31
+ #define STB_NUM_CHARS STB_FONT_consolas_24_latin1_NUM_CHARS
32
+ #define STB_MISSING_GLPYH 0x80 // Actually a control character.
33
+
34
+ // Max. number of chars the text overlay buffer can hold
35
+ #define MAX_CHAR_COUNT 1024
36
+
37
+
38
+ /**
39
+ * @internal
40
+ * @brief Given the lead byte of a UTF-8 sequence returns the expected length of the codepoint
41
+ * @param[in] leadByte The lead byte of a UTF-8 sequence
42
+ * @return The expected length of the codepoint */
43
+ [[nodiscard]] constexpr inline int sequenceLength(uint8_t leadByte) noexcept {
44
+ if ((leadByte & 0b1000'0000u) == 0b0000'0000u)
45
+ return 1;
46
+ if ((leadByte & 0b1110'0000u) == 0b1100'0000u)
47
+ return 2;
48
+ if ((leadByte & 0b1111'0000u) == 0b1110'0000u)
49
+ return 3;
50
+ if ((leadByte & 0b1111'1000u) == 0b1111'0000u)
51
+ return 4;
52
+
53
+ return 0;
54
+ }
55
+
56
+ /**
57
+ * @internal
58
+ * @brief Checks if the codepoint was coded as a longer than required sequence
59
+ * @param[in] codepoint The unicode codepoint
60
+ * @param[in] length The UTF-8 sequence length
61
+ * @return True if the sequence length was inappropriate for the given codepoint */
62
+ [[nodiscard]] constexpr inline bool isOverlongSequence(uint32_t codepoint, int length) noexcept {
63
+ if (codepoint < 0x80)
64
+ return length != 1;
65
+ else if (codepoint < 0x800)
66
+ return length != 2;
67
+ else if (codepoint < 0x10000)
68
+ return length != 3;
69
+ else
70
+ return false;
71
+ }
72
+
73
+ /**
74
+ * @internal
75
+ * @brief Checks if the codepoint is valid
76
+ * @param[in] codepoint The unicode codepoint
77
+ * @return True if the codepoint is a valid unicode codepoint */
78
+ [[nodiscard]] constexpr inline bool isCodepointValid(uint32_t codepoint) noexcept {
79
+ return codepoint <= 0x0010FFFFu
80
+ && !(0xD800u <= codepoint && codepoint <= 0xDBFFu);
81
+ }
82
+
83
+ /**
84
+ * @internal
85
+ * @brief Safely checks and advances a UTF-8 sequence iterator to the start of the next unicode codepoint
86
+ * @param[in] it iterator to be advanced
87
+ * @param[in] end iterator pointing to the end of the range
88
+ * @return True if the advance operation was successful and the advanced codepoint was a valid UTF-8 sequence */
89
+ template <typename Iterator>
90
+ [[nodiscard]] constexpr bool advanceUTF8(Iterator& it, Iterator end,
91
+ uint32_t& codepoint) noexcept {
92
+ if (it == end)
93
+ return false;
94
+
95
+ const auto length = sequenceLength(*it);
96
+ if (length == 0)
97
+ return false;
98
+
99
+ if (std::distance(it, end) < length)
100
+ return false;
101
+
102
+ for (int i = 1; i < length; ++i) {
103
+ const auto trailByte = *(it + i);
104
+ if ((static_cast<uint8_t>(trailByte) & 0b1100'0000u) != 0b1000'0000u)
105
+ return false;
106
+ }
107
+
108
+ codepoint = 0;
109
+ switch (length) {
110
+ case 1:
111
+ codepoint |= *it++;
112
+ break;
113
+ case 2:
114
+ codepoint |= (*it++ & 0b0001'1111u) << 6u;
115
+ codepoint |= (*it++ & 0b0011'1111u);
116
+ break;
117
+ case 3:
118
+ codepoint |= (*it++ & 0b0000'1111u) << 12u;
119
+ codepoint |= (*it++ & 0b0011'1111u) << 6u;
120
+ codepoint |= (*it++ & 0b0011'1111u);
121
+ break;
122
+ case 4:
123
+ codepoint |= (*it++ & 0b0000'0111u) << 18u;
124
+ codepoint |= (*it++ & 0b0011'1111u) << 12u;
125
+ codepoint |= (*it++ & 0b0011'1111u) << 6u;
126
+ codepoint |= (*it++ & 0b0011'1111u);
127
+ break;
128
+ }
129
+
130
+ if (!isCodepointValid(codepoint))
131
+ return false;
132
+
133
+ if (isOverlongSequence(codepoint, length))
134
+ return false;
135
+
136
+ return true;
137
+ }
138
+
139
+ // Mostly self-contained text overlay class
140
+ // todo : comment
141
+ class VulkanTextOverlay
142
+ {
143
+ private:
144
+ VkPhysicalDevice physicalDevice;
145
+ VkDevice device;
146
+ VkPhysicalDeviceMemoryProperties deviceMemoryProperties;
147
+ VkQueue queue;
148
+ VkFormat colorFormat;
149
+ VkFormat depthFormat;
150
+
151
+ uint32_t *frameBufferWidth;
152
+ uint32_t *frameBufferHeight;
153
+
154
+ VkSampler sampler;
155
+ VkImage image;
156
+ VkImageView view;
157
+ VkBuffer buffer;
158
+ VkDeviceMemory memory;
159
+ VkDeviceMemory imageMemory;
160
+ VkDescriptorPool descriptorPool;
161
+ VkDescriptorSetLayout descriptorSetLayout;
162
+ VkDescriptorSet descriptorSet;
163
+ VkPipelineLayout pipelineLayout;
164
+ VkPipelineCache pipelineCache;
165
+ VkPipeline pipeline;
166
+ VkRenderPass renderPass;
167
+ VkCommandPool commandPool;
168
+ std::vector<VkFramebuffer*> frameBuffers;
169
+ std::vector<VkPipelineShaderStageCreateInfo> shaderStages;
170
+
171
+ // Pointer to mapped vertex buffer
172
+ glm::vec4 *mapped = nullptr;
173
+ // Used during text updates
174
+ glm::vec4 *mappedLocal = nullptr;
175
+
176
+ stb_fontchar stbFontData[STB_NUM_CHARS];
177
+ uint32_t numLetters;
178
+
179
+ // Try to find appropriate memory type for a memory allocation
180
+ uint32_t getMemoryType(uint32_t typeBits, VkFlags properties)
181
+ {
182
+ for (uint32_t i = 0; i < 32; i++)
183
+ {
184
+ if ((typeBits & 1) == 1)
185
+ {
186
+ if ((deviceMemoryProperties.memoryTypes[i].propertyFlags & properties) == properties)
187
+ {
188
+ return i;
189
+ }
190
+ }
191
+ typeBits >>= 1;
192
+ }
193
+
194
+ // todo : throw error
195
+ return 0;
196
+ }
197
+
198
+ public:
199
+
200
+ enum TextAlign { alignLeft, alignCenter, alignRight };
201
+
202
+ bool visible = true;
203
+ bool invalidated = false;
204
+
205
+ std::vector<VkCommandBuffer> cmdBuffers;
206
+
207
+ VulkanTextOverlay(
208
+ VkPhysicalDevice physicalDevice,
209
+ VkDevice device,
210
+ VkQueue queue,
211
+ std::vector<VkFramebuffer> &framebuffers,
212
+ VkFormat colorformat,
213
+ VkFormat depthformat,
214
+ uint32_t *framebufferwidth,
215
+ uint32_t *framebufferheight,
216
+ std::vector<VkPipelineShaderStageCreateInfo> shaderstages)
217
+ {
218
+ this->physicalDevice = physicalDevice;
219
+ this->device = device;
220
+ this->queue = queue;
221
+ this->colorFormat = colorformat;
222
+ this->depthFormat = depthformat;
223
+
224
+ this->frameBuffers.resize(framebuffers.size());
225
+ for (uint32_t i = 0; i < framebuffers.size(); i++)
226
+ {
227
+ this->frameBuffers[i] = &framebuffers[i];
228
+ }
229
+
230
+ this->shaderStages = shaderstages;
231
+
232
+ this->frameBufferWidth = framebufferwidth;
233
+ this->frameBufferHeight = framebufferheight;
234
+
235
+ vkGetPhysicalDeviceMemoryProperties(physicalDevice, &deviceMemoryProperties);
236
+ cmdBuffers.resize(framebuffers.size());
237
+ prepareResources();
238
+ prepareRenderPass();
239
+ preparePipeline();
240
+ }
241
+
242
+ ~VulkanTextOverlay()
243
+ {
244
+ // Free up all Vulkan resources requested by the text overlay
245
+ vkDestroySampler(device, sampler, nullptr);
246
+ vkDestroyImage(device, image, nullptr);
247
+ vkDestroyImageView(device, view, nullptr);
248
+ vkDestroyBuffer(device, buffer, nullptr);
249
+ vkFreeMemory(device, memory, nullptr);
250
+ vkFreeMemory(device, imageMemory, nullptr);
251
+ vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
252
+ vkDestroyDescriptorPool(device, descriptorPool, nullptr);
253
+ vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
254
+ vkDestroyPipelineCache(device, pipelineCache, nullptr);
255
+ vkDestroyPipeline(device, pipeline, nullptr);
256
+ vkDestroyRenderPass(device, renderPass, nullptr);
257
+ vkFreeCommandBuffers(device, commandPool, static_cast<uint32_t>(cmdBuffers.size()), cmdBuffers.data());
258
+ vkDestroyCommandPool(device, commandPool, nullptr);
259
+ }
260
+
261
+ // Prepare all vulkan resources required to render the font
262
+ // The text overlay uses separate resources for descriptors (pool, sets, layouts), pipelines and command buffers
263
+ void prepareResources()
264
+ {
265
+ static unsigned char font24pixels[STB_FONT_HEIGHT][STB_FONT_WIDTH];
266
+ STB_FONT_NAME(stbFontData, font24pixels, STB_FONT_HEIGHT);
267
+
268
+ // Command buffer
269
+
270
+ // Pool
271
+ VkCommandPoolCreateInfo cmdPoolInfo = {};
272
+ cmdPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
273
+ cmdPoolInfo.queueFamilyIndex = 0; // todo : pass from example base / swap chain
274
+ cmdPoolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
275
+ VK_CHECK_RESULT(vkCreateCommandPool(device, &cmdPoolInfo, nullptr, &commandPool));
276
+
277
+ VkCommandBufferAllocateInfo cmdBufAllocateInfo =
278
+ vkTools::initializers::commandBufferAllocateInfo(
279
+ commandPool,
280
+ VK_COMMAND_BUFFER_LEVEL_PRIMARY,
281
+ (uint32_t)cmdBuffers.size());
282
+
283
+ VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, cmdBuffers.data()));
284
+
285
+ // Vertex buffer, 4 per character.
286
+ VkDeviceSize bufferSize = MAX_CHAR_COUNT * sizeof(glm::vec4) * 4;
287
+
288
+ VkBufferCreateInfo bufferInfo = vkTools::initializers::bufferCreateInfo(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, bufferSize);
289
+ VK_CHECK_RESULT(vkCreateBuffer(device, &bufferInfo, nullptr, &buffer));
290
+
291
+ VkMemoryRequirements memReqs;
292
+ VkMemoryAllocateInfo allocInfo = vkTools::initializers::memoryAllocateInfo();
293
+
294
+ vkGetBufferMemoryRequirements(device, buffer, &memReqs);
295
+ allocInfo.allocationSize = memReqs.size;
296
+ allocInfo.memoryTypeIndex = getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
297
+ VK_CHECK_RESULT(vkAllocateMemory(device, &allocInfo, nullptr, &memory));
298
+ VK_CHECK_RESULT(vkBindBufferMemory(device, buffer, memory, 0));
299
+
300
+ // Map persistent
301
+ VK_CHECK_RESULT(vkMapMemory(device, memory, 0, VK_WHOLE_SIZE, 0, (void **)&mapped));
302
+
303
+
304
+ // Font texture
305
+ VkImageCreateInfo imageInfo = vkTools::initializers::imageCreateInfo();
306
+ imageInfo.imageType = VK_IMAGE_TYPE_2D;
307
+ imageInfo.format = VK_FORMAT_R8_UNORM;
308
+ imageInfo.extent.width = STB_FONT_WIDTH;
309
+ imageInfo.extent.height = STB_FONT_HEIGHT;
310
+ imageInfo.extent.depth = 1;
311
+ imageInfo.mipLevels = 1;
312
+ imageInfo.arrayLayers = 1;
313
+ imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
314
+ imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
315
+ imageInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
316
+ imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
317
+ imageInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
318
+ VK_CHECK_RESULT(vkCreateImage(device, &imageInfo, nullptr, &image));
319
+
320
+ vkGetImageMemoryRequirements(device, image, &memReqs);
321
+ allocInfo.allocationSize = memReqs.size;
322
+ allocInfo.memoryTypeIndex = getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
323
+ VK_CHECK_RESULT(vkAllocateMemory(device, &allocInfo, nullptr, &imageMemory));
324
+ VK_CHECK_RESULT(vkBindImageMemory(device, image, imageMemory, 0));
325
+
326
+ // Staging
327
+
328
+ struct {
329
+ VkDeviceMemory memory;
330
+ VkBuffer buffer;
331
+ } stagingBuffer;
332
+
333
+ VkBufferCreateInfo bufferCreateInfo = vkTools::initializers::bufferCreateInfo();
334
+ bufferCreateInfo.size = allocInfo.allocationSize;
335
+ bufferCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
336
+ bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
337
+
338
+ VK_CHECK_RESULT(vkCreateBuffer(device, &bufferCreateInfo, nullptr, &stagingBuffer.buffer));
339
+
340
+ // Get memory requirements for the staging buffer (alignment, memory type bits)
341
+ vkGetBufferMemoryRequirements(device, stagingBuffer.buffer, &memReqs);
342
+
343
+ allocInfo.allocationSize = memReqs.size;
344
+ // Get memory type index for a host visible buffer
345
+ allocInfo.memoryTypeIndex = getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
346
+
347
+ VK_CHECK_RESULT(vkAllocateMemory(device, &allocInfo, nullptr, &stagingBuffer.memory));
348
+ VK_CHECK_RESULT(vkBindBufferMemory(device, stagingBuffer.buffer, stagingBuffer.memory, 0));
349
+
350
+ uint8_t *data;
351
+ VK_CHECK_RESULT(vkMapMemory(device, stagingBuffer.memory, 0, allocInfo.allocationSize, 0, (void **)&data));
352
+ memcpy(data, &font24pixels[0][0], STB_FONT_WIDTH * STB_FONT_HEIGHT);
353
+ vkUnmapMemory(device, stagingBuffer.memory);
354
+
355
+ // Copy to image
356
+
357
+ VkCommandBuffer copyCmd;
358
+ cmdBufAllocateInfo.commandBufferCount = 1;
359
+ VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, &copyCmd));
360
+
361
+ VkCommandBufferBeginInfo cmdBufInfo = vkTools::initializers::commandBufferBeginInfo();
362
+ VK_CHECK_RESULT(vkBeginCommandBuffer(copyCmd, &cmdBufInfo));
363
+
364
+ // Prepare for transfer
365
+ vkTools::setImageLayout(
366
+ copyCmd,
367
+ image,
368
+ VK_IMAGE_ASPECT_COLOR_BIT,
369
+ VK_IMAGE_LAYOUT_PREINITIALIZED,
370
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
371
+
372
+ VkBufferImageCopy bufferCopyRegion = {};
373
+ bufferCopyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
374
+ bufferCopyRegion.imageSubresource.mipLevel = 0;
375
+ bufferCopyRegion.imageSubresource.layerCount = 1;
376
+ bufferCopyRegion.imageExtent.width = STB_FONT_WIDTH;
377
+ bufferCopyRegion.imageExtent.height = STB_FONT_HEIGHT;
378
+ bufferCopyRegion.imageExtent.depth = 1;
379
+
380
+ vkCmdCopyBufferToImage(
381
+ copyCmd,
382
+ stagingBuffer.buffer,
383
+ image,
384
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
385
+ 1,
386
+ &bufferCopyRegion
387
+ );
388
+
389
+ // Prepare for shader read
390
+ vkTools::setImageLayout(
391
+ copyCmd,
392
+ image,
393
+ VK_IMAGE_ASPECT_COLOR_BIT,
394
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
395
+ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
396
+
397
+ VK_CHECK_RESULT(vkEndCommandBuffer(copyCmd));
398
+
399
+ VkSubmitInfo submitInfo = vkTools::initializers::submitInfo();
400
+ submitInfo.commandBufferCount = 1;
401
+ submitInfo.pCommandBuffers = &copyCmd;
402
+
403
+ VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE));
404
+ VK_CHECK_RESULT(vkQueueWaitIdle(queue));
405
+
406
+ vkFreeCommandBuffers(device, commandPool, 1, &copyCmd);
407
+ vkFreeMemory(device, stagingBuffer.memory, nullptr);
408
+ vkDestroyBuffer(device, stagingBuffer.buffer, nullptr);
409
+
410
+
411
+ VkImageViewCreateInfo imageViewInfo = vkTools::initializers::imageViewCreateInfo();
412
+ imageViewInfo.image = image;
413
+ imageViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
414
+ imageViewInfo.format = imageInfo.format;
415
+ imageViewInfo.components = {
416
+ VK_COMPONENT_SWIZZLE_IDENTITY,
417
+ VK_COMPONENT_SWIZZLE_IDENTITY,
418
+ VK_COMPONENT_SWIZZLE_IDENTITY,
419
+ VK_COMPONENT_SWIZZLE_IDENTITY
420
+ };
421
+ imageViewInfo.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
422
+
423
+ VK_CHECK_RESULT(vkCreateImageView(device, &imageViewInfo, nullptr, &view));
424
+
425
+ // Sampler
426
+ VkSamplerCreateInfo samplerInfo = vkTools::initializers::samplerCreateInfo();
427
+ samplerInfo.magFilter = VK_FILTER_LINEAR;
428
+ samplerInfo.minFilter = VK_FILTER_LINEAR;
429
+ samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
430
+ samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
431
+ samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
432
+ samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
433
+ samplerInfo.mipLodBias = 0.0f;
434
+ samplerInfo.compareOp = VK_COMPARE_OP_NEVER;
435
+ samplerInfo.minLod = 0.0f;
436
+ samplerInfo.maxLod = 1.0f;
437
+ samplerInfo.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
438
+ samplerInfo.anisotropyEnable = VK_FALSE;
439
+ samplerInfo.maxAnisotropy = 1.0;
440
+ VK_CHECK_RESULT(vkCreateSampler(device, &samplerInfo, nullptr, &sampler));
441
+
442
+ // Descriptor
443
+ // Font uses a separate descriptor pool
444
+ std::array<VkDescriptorPoolSize, 1> poolSizes;
445
+ poolSizes[0] = vkTools::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1);
446
+
447
+ VkDescriptorPoolCreateInfo descriptorPoolInfo =
448
+ vkTools::initializers::descriptorPoolCreateInfo(
449
+ static_cast<uint32_t>(poolSizes.size()),
450
+ poolSizes.data(),
451
+ 1);
452
+
453
+ VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool));
454
+
455
+ // Descriptor set layout
456
+ std::array<VkDescriptorSetLayoutBinding, 1> setLayoutBindings;
457
+ setLayoutBindings[0] = vkTools::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, 0);
458
+
459
+ VkDescriptorSetLayoutCreateInfo descriptorSetLayoutInfo =
460
+ vkTools::initializers::descriptorSetLayoutCreateInfo(
461
+ setLayoutBindings.data(),
462
+ static_cast<uint32_t>(setLayoutBindings.size()));
463
+
464
+ VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorSetLayoutInfo, nullptr, &descriptorSetLayout));
465
+
466
+ // Pipeline layout
467
+ VkPipelineLayoutCreateInfo pipelineLayoutInfo =
468
+ vkTools::initializers::pipelineLayoutCreateInfo(
469
+ &descriptorSetLayout,
470
+ 1);
471
+
472
+ VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutInfo, nullptr, &pipelineLayout));
473
+
474
+ // Descriptor set
475
+ VkDescriptorSetAllocateInfo descriptorSetAllocInfo =
476
+ vkTools::initializers::descriptorSetAllocateInfo(
477
+ descriptorPool,
478
+ &descriptorSetLayout,
479
+ 1);
480
+
481
+ VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &descriptorSetAllocInfo, &descriptorSet));
482
+
483
+ VkDescriptorImageInfo texDescriptor =
484
+ vkTools::initializers::descriptorImageInfo(
485
+ sampler,
486
+ view,
487
+ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
488
+
489
+ std::array<VkWriteDescriptorSet, 1> writeDescriptorSets;
490
+ writeDescriptorSets[0] = vkTools::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 0, &texDescriptor);
491
+ vkUpdateDescriptorSets(device, static_cast<uint32_t>(writeDescriptorSets.size()), writeDescriptorSets.data(), 0, NULL);
492
+
493
+ // Pipeline cache
494
+ VkPipelineCacheCreateInfo pipelineCacheCreateInfo = {};
495
+ pipelineCacheCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
496
+ VK_CHECK_RESULT(vkCreatePipelineCache(device, &pipelineCacheCreateInfo, nullptr, &pipelineCache));
497
+ }
498
+
499
+ // Prepare a separate pipeline for the font rendering decoupled from the main application
500
+ void preparePipeline()
501
+ {
502
+ VkPipelineInputAssemblyStateCreateInfo inputAssemblyState =
503
+ vkTools::initializers::pipelineInputAssemblyStateCreateInfo(
504
+ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
505
+ 0,
506
+ // primmitiveRestartEnable not needed but disabling it results in a MoltenVK
507
+ // feature not present warning.
508
+ VK_TRUE);
509
+
510
+ VkPipelineRasterizationStateCreateInfo rasterizationState =
511
+ vkTools::initializers::pipelineRasterizationStateCreateInfo(
512
+ VK_POLYGON_MODE_FILL,
513
+ VK_CULL_MODE_BACK_BIT,
514
+ VK_FRONT_FACE_CLOCKWISE,
515
+ 0);
516
+ // Because we haven't enabled the depthClamp device feature.
517
+ rasterizationState.depthClampEnable = VK_FALSE;
518
+
519
+ // Enable blending
520
+ VkPipelineColorBlendAttachmentState blendAttachmentState =
521
+ vkTools::initializers::pipelineColorBlendAttachmentState(0xf, VK_TRUE);
522
+
523
+ blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_ONE;
524
+ blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE;
525
+ blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD;
526
+ blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
527
+ blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
528
+ blendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD;
529
+ blendAttachmentState.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
530
+
531
+ VkPipelineColorBlendStateCreateInfo colorBlendState =
532
+ vkTools::initializers::pipelineColorBlendStateCreateInfo(
533
+ 1,
534
+ &blendAttachmentState);
535
+
536
+ VkPipelineDepthStencilStateCreateInfo depthStencilState =
537
+ vkTools::initializers::pipelineDepthStencilStateCreateInfo(
538
+ VK_FALSE,
539
+ VK_FALSE,
540
+ VK_COMPARE_OP_LESS_OR_EQUAL);
541
+
542
+ VkPipelineViewportStateCreateInfo viewportState =
543
+ vkTools::initializers::pipelineViewportStateCreateInfo(1, 1, 0);
544
+
545
+ VkPipelineMultisampleStateCreateInfo multisampleState =
546
+ vkTools::initializers::pipelineMultisampleStateCreateInfo(
547
+ VK_SAMPLE_COUNT_1_BIT,
548
+ 0);
549
+
550
+ std::vector<VkDynamicState> dynamicStateEnables = {
551
+ VK_DYNAMIC_STATE_VIEWPORT,
552
+ VK_DYNAMIC_STATE_SCISSOR
553
+ };
554
+
555
+ VkPipelineDynamicStateCreateInfo dynamicState =
556
+ vkTools::initializers::pipelineDynamicStateCreateInfo(
557
+ dynamicStateEnables.data(),
558
+ static_cast<uint32_t>(dynamicStateEnables.size()),
559
+ 0);
560
+
561
+ std::array<VkVertexInputBindingDescription, 2> vertexBindings = {};
562
+ vertexBindings[0] = vkTools::initializers::vertexInputBindingDescription(0, sizeof(glm::vec4), VK_VERTEX_INPUT_RATE_VERTEX);
563
+ vertexBindings[1] = vkTools::initializers::vertexInputBindingDescription(1, sizeof(glm::vec4), VK_VERTEX_INPUT_RATE_VERTEX);
564
+
565
+ std::array<VkVertexInputAttributeDescription, 2> vertexAttribs = {};
566
+ // Position
567
+ vertexAttribs[0] = vkTools::initializers::vertexInputAttributeDescription(0, 0, VK_FORMAT_R32G32_SFLOAT, 0);
568
+ // UV
569
+ vertexAttribs[1] = vkTools::initializers::vertexInputAttributeDescription(1, 1, VK_FORMAT_R32G32_SFLOAT, sizeof(glm::vec2));
570
+
571
+ VkPipelineVertexInputStateCreateInfo inputState = vkTools::initializers::pipelineVertexInputStateCreateInfo();
572
+ inputState.vertexBindingDescriptionCount = static_cast<uint32_t>(vertexBindings.size());
573
+ inputState.pVertexBindingDescriptions = vertexBindings.data();
574
+ inputState.vertexAttributeDescriptionCount = static_cast<uint32_t>(vertexAttribs.size());
575
+ inputState.pVertexAttributeDescriptions = vertexAttribs.data();
576
+
577
+ VkGraphicsPipelineCreateInfo pipelineCreateInfo =
578
+ vkTools::initializers::pipelineCreateInfo(
579
+ pipelineLayout,
580
+ renderPass,
581
+ 0);
582
+
583
+ pipelineCreateInfo.pVertexInputState = &inputState;
584
+ pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState;
585
+ pipelineCreateInfo.pRasterizationState = &rasterizationState;
586
+ pipelineCreateInfo.pColorBlendState = &colorBlendState;
587
+ pipelineCreateInfo.pMultisampleState = &multisampleState;
588
+ pipelineCreateInfo.pViewportState = &viewportState;
589
+ pipelineCreateInfo.pDepthStencilState = &depthStencilState;
590
+ pipelineCreateInfo.pDynamicState = &dynamicState;
591
+ pipelineCreateInfo.stageCount = static_cast<uint32_t>(shaderStages.size());
592
+ pipelineCreateInfo.pStages = shaderStages.data();
593
+
594
+ VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipeline));
595
+ }
596
+
597
+ // Prepare a separate render pass for rendering the text as an overlay
598
+ void prepareRenderPass()
599
+ {
600
+ VkAttachmentDescription attachments[2] = {};
601
+
602
+ // Color attachment
603
+ attachments[0].format = colorFormat;
604
+ attachments[0].samples = VK_SAMPLE_COUNT_1_BIT;
605
+ // Don't clear the framebuffer (like the renderpass from the example does)
606
+ attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
607
+ attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
608
+ attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
609
+ attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
610
+ attachments[0].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
611
+ attachments[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
612
+
613
+ // Depth attachment
614
+ attachments[1].format = depthFormat;
615
+ attachments[1].samples = VK_SAMPLE_COUNT_1_BIT;
616
+ attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
617
+ attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
618
+ attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
619
+ attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
620
+ attachments[1].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
621
+ attachments[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
622
+
623
+ VkAttachmentReference colorReference = {};
624
+ colorReference.attachment = 0;
625
+ colorReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
626
+
627
+ VkAttachmentReference depthReference = {};
628
+ depthReference.attachment = 1;
629
+ depthReference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
630
+
631
+ VkSubpassDescription subpass = {};
632
+ subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
633
+ subpass.flags = 0;
634
+ subpass.inputAttachmentCount = 0;
635
+ subpass.pInputAttachments = NULL;
636
+ subpass.colorAttachmentCount = 1;
637
+ subpass.pColorAttachments = &colorReference;
638
+ subpass.pResolveAttachments = NULL;
639
+ subpass.pDepthStencilAttachment = &depthReference;
640
+ subpass.preserveAttachmentCount = 0;
641
+ subpass.pPreserveAttachments = NULL;
642
+
643
+ VkRenderPassCreateInfo renderPassInfo = {};
644
+ renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
645
+ renderPassInfo.pNext = NULL;
646
+ renderPassInfo.attachmentCount = 2;
647
+ renderPassInfo.pAttachments = attachments;
648
+ renderPassInfo.subpassCount = 1;
649
+ renderPassInfo.pSubpasses = &subpass;
650
+ renderPassInfo.dependencyCount = 0;
651
+ renderPassInfo.pDependencies = NULL;
652
+
653
+ VK_CHECK_RESULT(vkCreateRenderPass(device, &renderPassInfo, nullptr, &renderPass));
654
+ }
655
+
656
+ // Map buffer
657
+ void beginTextUpdate()
658
+ {
659
+ mappedLocal = mapped;
660
+ numLetters = 0;
661
+ }
662
+
663
+ // Add text to the current buffer
664
+ // todo : drop shadow? color attribute?
665
+ void addText(std::string text, float x, float y, TextAlign align)
666
+ {
667
+ if (numLetters == MAX_CHAR_COUNT)
668
+ return;
669
+
670
+ assert(mapped != nullptr);
671
+
672
+ const float charW = 1.5f / *frameBufferWidth;
673
+ const float charH = 1.5f / *frameBufferHeight;
674
+
675
+ float fbW = (float)*frameBufferWidth;
676
+ float fbH = (float)*frameBufferHeight;
677
+ x = (x / fbW * 2.0f) - 1.0f;
678
+ y = (y / fbH * 2.0f) - 1.0f;
679
+
680
+ // Calculate text width
681
+ float textWidth = 0;
682
+ uint32_t codepoint;
683
+ auto it = text.begin();
684
+ while (it != text.end())
685
+ {
686
+ if (!advanceUTF8(it, text.end(), codepoint))
687
+ break;
688
+ // TODO: Get a UTF8 font. Consider changing to Dear ImGUI
689
+ // https://github.com/ocornut/imgui.
690
+ // Placeholder to avoid crashing.
691
+ if (codepoint > STB_NUM_CHARS + STB_FIRST_CHAR)
692
+ codepoint = STB_MISSING_GLPYH;
693
+ stb_fontchar *charData = &stbFontData[(uint32_t)codepoint - STB_FIRST_CHAR];
694
+ textWidth += charData->advance * charW;
695
+ }
696
+ switch (align)
697
+ {
698
+ case alignRight:
699
+ x -= textWidth;
700
+ break;
701
+ case alignCenter:
702
+ x -= textWidth / 2.0f;
703
+ break;
704
+ case alignLeft:
705
+ break;
706
+ }
707
+
708
+ // Generate a uv mapped quad per char in the new text
709
+ it = text.begin();
710
+ while (it != text.end())
711
+ {
712
+ if (!advanceUTF8(it, text.end(), codepoint))
713
+ break;
714
+ if (codepoint > STB_NUM_CHARS + STB_FIRST_CHAR)
715
+ codepoint = STB_MISSING_GLPYH;
716
+
717
+ stb_fontchar *charData = &stbFontData[(uint32_t)codepoint - STB_FIRST_CHAR];
718
+
719
+ mappedLocal->x = (x + (float)charData->x0 * charW);
720
+ mappedLocal->y = (y + (float)charData->y0 * charH);
721
+ mappedLocal->z = charData->s0;
722
+ mappedLocal->w = charData->t0;
723
+ mappedLocal++;
724
+
725
+ mappedLocal->x = (x + (float)charData->x1 * charW);
726
+ mappedLocal->y = (y + (float)charData->y0 * charH);
727
+ mappedLocal->z = charData->s1;
728
+ mappedLocal->w = charData->t0;
729
+ mappedLocal++;
730
+
731
+ mappedLocal->x = (x + (float)charData->x0 * charW);
732
+ mappedLocal->y = (y + (float)charData->y1 * charH);
733
+ mappedLocal->z = charData->s0;
734
+ mappedLocal->w = charData->t1;
735
+ mappedLocal++;
736
+
737
+ mappedLocal->x = (x + (float)charData->x1 * charW);
738
+ mappedLocal->y = (y + (float)charData->y1 * charH);
739
+ mappedLocal->z = charData->s1;
740
+ mappedLocal->w = charData->t1;
741
+ mappedLocal++;
742
+
743
+ x += charData->advance * charW;
744
+
745
+ numLetters++;
746
+
747
+ if (numLetters == MAX_CHAR_COUNT)
748
+ break; // Truncate the text.
749
+ }
750
+ }
751
+ // Unmap buffer and update command buffers
752
+ void endTextUpdate()
753
+ {
754
+ updateCommandBuffers();
755
+ }
756
+
757
+ // Needs to be called by the application
758
+ void updateCommandBuffers()
759
+ {
760
+ VkCommandBufferBeginInfo cmdBufInfo = vkTools::initializers::commandBufferBeginInfo();
761
+
762
+ VkRenderPassBeginInfo renderPassBeginInfo = vkTools::initializers::renderPassBeginInfo();
763
+ renderPassBeginInfo.renderPass = renderPass;
764
+ renderPassBeginInfo.renderArea.extent.width = *frameBufferWidth;
765
+ renderPassBeginInfo.renderArea.extent.height = *frameBufferHeight;
766
+ renderPassBeginInfo.clearValueCount = 0;
767
+ renderPassBeginInfo.pClearValues = nullptr;
768
+
769
+ for (uint32_t i = 0; i < cmdBuffers.size(); ++i)
770
+ {
771
+ renderPassBeginInfo.framebuffer = *frameBuffers[i];
772
+
773
+ VK_CHECK_RESULT(vkBeginCommandBuffer(cmdBuffers[i], &cmdBufInfo));
774
+
775
+ if (vkDebug::DebugMarker::active)
776
+ {
777
+ vkDebug::DebugMarker::beginRegion(cmdBuffers[i], "Text overlay", glm::vec4(1.0f, 0.94f, 0.3f, 1.0f));
778
+ }
779
+
780
+ vkCmdBeginRenderPass(cmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
781
+
782
+ VkViewport viewport = vkTools::initializers::viewport((float)*frameBufferWidth, (float)*frameBufferHeight, 0.0f, 1.0f);
783
+ vkCmdSetViewport(cmdBuffers[i], 0, 1, &viewport);
784
+
785
+ VkRect2D scissor = vkTools::initializers::rect2D(*frameBufferWidth, *frameBufferHeight, 0, 0);
786
+ vkCmdSetScissor(cmdBuffers[i], 0, 1, &scissor);
787
+
788
+ vkCmdBindPipeline(cmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
789
+ vkCmdBindDescriptorSets(cmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, NULL);
790
+
791
+ VkDeviceSize offsets = 0;
792
+ vkCmdBindVertexBuffers(cmdBuffers[i], 0, 1, &buffer, &offsets);
793
+ vkCmdBindVertexBuffers(cmdBuffers[i], 1, 1, &buffer, &offsets);
794
+ for (uint32_t j = 0; j < numLetters; j++)
795
+ {
796
+ vkCmdDraw(cmdBuffers[i], 4, 1, j * 4, 0);
797
+ }
798
+
799
+ vkCmdEndRenderPass(cmdBuffers[i]);
800
+
801
+ if (vkDebug::DebugMarker::active)
802
+ {
803
+ vkDebug::DebugMarker::endRegion(cmdBuffers[i]);
804
+ }
805
+
806
+ VK_CHECK_RESULT(vkEndCommandBuffer(cmdBuffers[i]));
807
+ }
808
+ }
809
+
810
+ // Submit the text command buffers to a queue
811
+ void submit(VkQueue targetQueue, uint32_t bufferindex, VkSubmitInfo submitInfo)
812
+ {
813
+ if (!visible)
814
+ {
815
+ return;
816
+ }
817
+
818
+ submitInfo.pCommandBuffers = &cmdBuffers[bufferindex];
819
+ submitInfo.commandBufferCount = 1;
820
+
821
+ VK_CHECK_RESULT(vkQueueSubmit(targetQueue, 1, &submitInfo, VK_NULL_HANDLE));
822
+ }
823
+
824
+ void reallocateCommandBuffers()
825
+ {
826
+ vkFreeCommandBuffers(device, commandPool, static_cast<uint32_t>(cmdBuffers.size()), cmdBuffers.data());
827
+
828
+ VkCommandBufferAllocateInfo cmdBufAllocateInfo =
829
+ vkTools::initializers::commandBufferAllocateInfo(
830
+ commandPool,
831
+ VK_COMMAND_BUFFER_LEVEL_PRIMARY,
832
+ static_cast<uint32_t>(cmdBuffers.size()));
833
+
834
+ VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, cmdBuffers.data()));
835
+ }
836
+
837
+ };
838
+
839
+ // vi: set sw=2 ts=4 expandtab:
third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/vulkantools.cpp ADDED
@@ -0,0 +1,918 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright 2016 Sascha Willems - www.saschawillems.de
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * Assorted commonly used Vulkan helper functions
6
+ *
7
+ * asserts on unhandled cases in setImageLayout added by Mark Callow, 2017.3.3.
8
+ */
9
+
10
+ #if defined(_WIN32)
11
+ #define _CRT_SECURE_NO_WARNINGS // For fopen
12
+ #endif
13
+
14
+ #include "vulkantools.h"
15
+ #include "unused.h"
16
+
17
+ namespace vkTools
18
+ {
19
+
20
+ VkBool32 checkGlobalExtensionPresent(const char* extensionName)
21
+ {
22
+ uint32_t extensionCount = 0;
23
+ std::vector<VkExtensionProperties> extensions;
24
+ vkEnumerateInstanceExtensionProperties(NULL, &extensionCount, NULL);
25
+ extensions.resize(extensionCount);
26
+ vkEnumerateInstanceExtensionProperties(NULL, &extensionCount, extensions.data());
27
+ for (auto& ext : extensions)
28
+ {
29
+ if (!strcmp(extensionName, ext.extensionName))
30
+ {
31
+ return true;
32
+ }
33
+ }
34
+ return false;
35
+ }
36
+
37
+ VkBool32 checkDeviceExtensionPresent(VkPhysicalDevice physicalDevice, const char* extensionName)
38
+ {
39
+ uint32_t extensionCount = 0;
40
+ std::vector<VkExtensionProperties> extensions;
41
+ vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &extensionCount, NULL);
42
+ extensions.resize(extensionCount);
43
+ vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &extensionCount, extensions.data());
44
+ for (auto& ext : extensions)
45
+ {
46
+ if (!strcmp(extensionName, ext.extensionName))
47
+ {
48
+ return true;
49
+ }
50
+ }
51
+ return false;
52
+ }
53
+
54
+ std::string errorString(VkResult errorCode)
55
+ {
56
+ switch (errorCode)
57
+ {
58
+ #define STR(r) case VK_ ##r: return #r
59
+ STR(NOT_READY);
60
+ STR(TIMEOUT);
61
+ STR(EVENT_SET);
62
+ STR(EVENT_RESET);
63
+ STR(INCOMPLETE);
64
+ STR(ERROR_OUT_OF_HOST_MEMORY);
65
+ STR(ERROR_OUT_OF_DEVICE_MEMORY);
66
+ STR(ERROR_INITIALIZATION_FAILED);
67
+ STR(ERROR_DEVICE_LOST);
68
+ STR(ERROR_MEMORY_MAP_FAILED);
69
+ STR(ERROR_LAYER_NOT_PRESENT);
70
+ STR(ERROR_EXTENSION_NOT_PRESENT);
71
+ STR(ERROR_FEATURE_NOT_PRESENT);
72
+ STR(ERROR_INCOMPATIBLE_DRIVER);
73
+ STR(ERROR_TOO_MANY_OBJECTS);
74
+ STR(ERROR_FORMAT_NOT_SUPPORTED);
75
+ STR(ERROR_SURFACE_LOST_KHR);
76
+ STR(ERROR_NATIVE_WINDOW_IN_USE_KHR);
77
+ STR(SUBOPTIMAL_KHR);
78
+ STR(ERROR_OUT_OF_DATE_KHR);
79
+ STR(ERROR_INCOMPATIBLE_DISPLAY_KHR);
80
+ STR(ERROR_VALIDATION_FAILED_EXT);
81
+ STR(ERROR_INVALID_SHADER_NV);
82
+ #undef STR
83
+ default:
84
+ return "UNKNOWN_ERROR";
85
+ }
86
+ }
87
+
88
+ VkBool32 getSupportedDepthFormat(VkPhysicalDevice physicalDevice, VkFormat *depthFormat)
89
+ {
90
+ // Since all depth formats may be optional, we need to find a suitable depth format to use
91
+ // Start with the highest precision packed format
92
+ std::vector<VkFormat> depthFormats = {
93
+ VK_FORMAT_D32_SFLOAT_S8_UINT,
94
+ VK_FORMAT_D32_SFLOAT,
95
+ VK_FORMAT_D24_UNORM_S8_UINT,
96
+ VK_FORMAT_D16_UNORM_S8_UINT,
97
+ VK_FORMAT_D16_UNORM
98
+ };
99
+
100
+ for (auto& format : depthFormats)
101
+ {
102
+ VkFormatProperties formatProps;
103
+ vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &formatProps);
104
+ // Format must support depth stencil attachment for optimal tiling
105
+ if (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
106
+ {
107
+ *depthFormat = format;
108
+ return true;
109
+ }
110
+ }
111
+
112
+ return false;
113
+ }
114
+
115
+ // Create an image memory barrier for changing the layout of
116
+ // an image and put it into an active command buffer
117
+ // See chapter 11.4 "Image Layout" for details
118
+
119
+ void setImageLayout(
120
+ VkCommandBuffer cmdbuffer,
121
+ VkImage image,
122
+ VkImageAspectFlags /*aspectMask*/,
123
+ VkImageLayout oldImageLayout,
124
+ VkImageLayout newImageLayout,
125
+ VkImageSubresourceRange subresourceRange)
126
+ {
127
+ // Create an image barrier object
128
+ VkImageMemoryBarrier imageMemoryBarrier = vkTools::initializers::imageMemoryBarrier();
129
+ imageMemoryBarrier.oldLayout = oldImageLayout;
130
+ imageMemoryBarrier.newLayout = newImageLayout;
131
+ imageMemoryBarrier.image = image;
132
+ imageMemoryBarrier.subresourceRange = subresourceRange;
133
+
134
+ // Source layouts (old)
135
+ // Source access mask controls actions that have to be finished on the old layout
136
+ // before it will be transitioned to the new layout
137
+ switch (oldImageLayout)
138
+ {
139
+ case VK_IMAGE_LAYOUT_UNDEFINED:
140
+ // Image layout is undefined (or does not matter)
141
+ // Only valid as initial layout
142
+ // No flags required, listed only for completeness
143
+ imageMemoryBarrier.srcAccessMask = 0;
144
+ break;
145
+
146
+ case VK_IMAGE_LAYOUT_PREINITIALIZED:
147
+ // Image is preinitialized
148
+ // Only valid as initial layout for linear images, preserves memory contents
149
+ // Make sure host writes have been finished
150
+ imageMemoryBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
151
+ break;
152
+
153
+ case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
154
+ // Image is a color attachment
155
+ // Make sure any writes to the color buffer have been finished
156
+ imageMemoryBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
157
+ break;
158
+
159
+ case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
160
+ // Image is a depth/stencil attachment
161
+ // Make sure any writes to the depth/stencil buffer have been finished
162
+ imageMemoryBarrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
163
+ break;
164
+
165
+ case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
166
+ // Image is a transfer source
167
+ // Make sure any reads from the image have been finished
168
+ imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
169
+ break;
170
+
171
+ case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
172
+ // Image is a transfer destination
173
+ // Make sure any writes to the image have been finished
174
+ imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
175
+ break;
176
+
177
+ case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
178
+ // Image is read by a shader
179
+ // Make sure any shader reads from the image have been finished
180
+ imageMemoryBarrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
181
+ break;
182
+
183
+ default:
184
+ assert(0); // Attempt to use unhandled case.
185
+ }
186
+
187
+ // Target layouts (new)
188
+ // Destination access mask controls the dependency for the new image layout
189
+ switch (newImageLayout)
190
+ {
191
+ case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
192
+ // Image will be used as a transfer destination
193
+ // Make sure any writes to the image have been finished
194
+ imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
195
+ break;
196
+
197
+ case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
198
+ // Image will be used as a transfer source
199
+ // Make sure any reads from and writes to the image have been finished
200
+ imageMemoryBarrier.srcAccessMask = imageMemoryBarrier.srcAccessMask | VK_ACCESS_TRANSFER_READ_BIT;
201
+ imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
202
+ break;
203
+
204
+ case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
205
+ // Image will be used as a color attachment
206
+ // Make sure any writes to the color buffer have been finished
207
+ imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
208
+ imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
209
+ break;
210
+
211
+ case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
212
+ // Image layout will be used as a depth/stencil attachment
213
+ // Make sure any writes to depth/stencil buffer have been finished
214
+ imageMemoryBarrier.dstAccessMask = imageMemoryBarrier.dstAccessMask | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
215
+ break;
216
+
217
+ case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
218
+ // Image will be read in a shader (sampler, input attachment)
219
+ // Make sure any writes to the image have been finished
220
+ if (imageMemoryBarrier.srcAccessMask == 0)
221
+ {
222
+ imageMemoryBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
223
+ }
224
+ imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
225
+ break;
226
+
227
+ default:
228
+ assert(0); // Attempt to use unhandled case.
229
+ }
230
+
231
+ // Put barrier on top
232
+ VkPipelineStageFlags srcStageFlags = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
233
+ VkPipelineStageFlags destStageFlags = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
234
+
235
+ // Put barrier inside setup command buffer
236
+ vkCmdPipelineBarrier(
237
+ cmdbuffer,
238
+ srcStageFlags,
239
+ destStageFlags,
240
+ 0,
241
+ 0, nullptr,
242
+ 0, nullptr,
243
+ 1, &imageMemoryBarrier);
244
+ }
245
+
246
+ // Fixed sub resource on first mip level and layer
247
+ void setImageLayout(
248
+ VkCommandBuffer cmdbuffer,
249
+ VkImage image,
250
+ VkImageAspectFlags aspectMask,
251
+ VkImageLayout oldImageLayout,
252
+ VkImageLayout newImageLayout)
253
+ {
254
+ VkImageSubresourceRange subresourceRange = {};
255
+ subresourceRange.aspectMask = aspectMask;
256
+ subresourceRange.baseMipLevel = 0;
257
+ subresourceRange.levelCount = 1;
258
+ subresourceRange.layerCount = 1;
259
+ setImageLayout(cmdbuffer, image, aspectMask, oldImageLayout, newImageLayout, subresourceRange);
260
+ }
261
+
262
+ void exitFatal(std::string message, std::string caption)
263
+ {
264
+ (void)SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, caption.c_str(),
265
+ message.c_str(), NULL);
266
+ std::cerr << message << "\n";
267
+ exit(1);
268
+ }
269
+
270
+ std::string readTextFile(const char *fileName)
271
+ {
272
+ std::string fileContent;
273
+ std::ifstream fileStream(fileName, std::ios::in);
274
+ if (!fileStream.is_open()) {
275
+ printf("File %s not found\n", fileName);
276
+ return "";
277
+ }
278
+ std::string line = "";
279
+ while (!fileStream.eof()) {
280
+ getline(fileStream, line);
281
+ fileContent.append(line + "\n");
282
+ }
283
+ fileStream.close();
284
+ return fileContent;
285
+ }
286
+
287
+ #if defined(__ANDROID__)
288
+ // Android shaders are stored as assets in the apk
289
+ // So they need to be loaded via the asset manager
290
+ VkShaderModule loadShader(AAssetManager* assetManager, const char *fileName, VkDevice device, VkShaderStageFlagBits stage)
291
+ {
292
+ // Load shader from compressed asset
293
+ AAsset* asset = AAssetManager_open(assetManager, fileName, AASSET_MODE_STREAMING);
294
+ assert(asset);
295
+ size_t size = AAsset_getLength(asset);
296
+ assert(size > 0);
297
+
298
+ char *shaderCode = new char[size];
299
+ AAsset_read(asset, shaderCode, size);
300
+ AAsset_close(asset);
301
+
302
+ VkShaderModule shaderModule;
303
+ VkShaderModuleCreateInfo moduleCreateInfo;
304
+ moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
305
+ moduleCreateInfo.pNext = NULL;
306
+ moduleCreateInfo.codeSize = size;
307
+ moduleCreateInfo.pCode = (uint32_t*)shaderCode;
308
+ moduleCreateInfo.flags = 0;
309
+
310
+ VK_CHECK_RESULT(vkCreateShaderModule(device, &moduleCreateInfo, NULL, &shaderModule));
311
+
312
+ delete[] shaderCode;
313
+
314
+ return shaderModule;
315
+ }
316
+ #else
317
+ VkShaderModule loadShader(const char *fileName, VkDevice device, VkShaderStageFlagBits /*stage*/)
318
+ {
319
+ size_t size;
320
+
321
+ FILE *fp = fopen(fileName, "rb");
322
+ assert(fp);
323
+
324
+ fseek(fp, 0L, SEEK_END);
325
+ size = ftell(fp);
326
+
327
+ fseek(fp, 0L, SEEK_SET);
328
+
329
+ //shaderCode = malloc(size);
330
+ char *shaderCode = new char[size];
331
+ U_ASSERT_ONLY size_t retval = fread(shaderCode, size, 1, fp);
332
+ assert(retval == 1);
333
+ (void)retval; // Supress VC++ unused variable warning for Release config.
334
+ assert(size > 0);
335
+
336
+ fclose(fp);
337
+
338
+ VkShaderModule shaderModule;
339
+ VkShaderModuleCreateInfo moduleCreateInfo;
340
+ moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
341
+ moduleCreateInfo.pNext = NULL;
342
+ moduleCreateInfo.codeSize = size;
343
+ moduleCreateInfo.pCode = (uint32_t*)shaderCode;
344
+ moduleCreateInfo.flags = 0;
345
+
346
+ VK_CHECK_RESULT(vkCreateShaderModule(device, &moduleCreateInfo, NULL, &shaderModule));
347
+
348
+ delete[] shaderCode;
349
+
350
+ return shaderModule;
351
+ }
352
+ #endif
353
+
354
+ VkShaderModule loadShaderGLSL(const char *fileName, VkDevice device, VkShaderStageFlagBits stage)
355
+ {
356
+ std::string shaderSrc = readTextFile(fileName);
357
+ const char *shaderCode = shaderSrc.c_str();
358
+ size_t size = strlen(shaderCode);
359
+ assert(size > 0);
360
+
361
+ VkShaderModule shaderModule;
362
+ VkShaderModuleCreateInfo moduleCreateInfo;
363
+ moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
364
+ moduleCreateInfo.pNext = NULL;
365
+ moduleCreateInfo.codeSize = 3 * sizeof(uint32_t) + size + 1;
366
+ moduleCreateInfo.pCode = (uint32_t*)malloc(moduleCreateInfo.codeSize);
367
+ moduleCreateInfo.flags = 0;
368
+
369
+ // Magic SPV number
370
+ ((uint32_t *)moduleCreateInfo.pCode)[0] = 0x07230203;
371
+ ((uint32_t *)moduleCreateInfo.pCode)[1] = 0;
372
+ ((uint32_t *)moduleCreateInfo.pCode)[2] = stage;
373
+ memcpy(((uint32_t *)moduleCreateInfo.pCode + 3), shaderCode, size + 1);
374
+
375
+ VK_CHECK_RESULT(vkCreateShaderModule(device, &moduleCreateInfo, NULL, &shaderModule));
376
+
377
+ return shaderModule;
378
+ }
379
+
380
+ VkImageMemoryBarrier prePresentBarrier(VkImage presentImage)
381
+ {
382
+ VkImageMemoryBarrier imageMemoryBarrier = vkTools::initializers::imageMemoryBarrier();
383
+ imageMemoryBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
384
+ imageMemoryBarrier.dstAccessMask = 0;
385
+ imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
386
+ imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
387
+ imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
388
+ imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
389
+ imageMemoryBarrier.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
390
+ imageMemoryBarrier.image = presentImage;
391
+ return imageMemoryBarrier;
392
+ }
393
+
394
+ VkImageMemoryBarrier postPresentBarrier(VkImage presentImage)
395
+ {
396
+ VkImageMemoryBarrier imageMemoryBarrier = vkTools::initializers::imageMemoryBarrier();
397
+ imageMemoryBarrier.srcAccessMask = 0;
398
+ imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
399
+ imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
400
+ imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
401
+ imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
402
+ imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
403
+ imageMemoryBarrier.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
404
+ imageMemoryBarrier.image = presentImage;
405
+ return imageMemoryBarrier;
406
+ }
407
+
408
+ void destroyUniformData(VkDevice device, vkTools::UniformData *uniformData)
409
+ {
410
+ if (uniformData->mapped != nullptr)
411
+ {
412
+ vkUnmapMemory(device, uniformData->memory);
413
+ }
414
+ vkDestroyBuffer(device, uniformData->buffer, nullptr);
415
+ vkFreeMemory(device, uniformData->memory, nullptr);
416
+ }
417
+ }
418
+
419
+ VkMemoryAllocateInfo vkTools::initializers::memoryAllocateInfo()
420
+ {
421
+ VkMemoryAllocateInfo memAllocInfo = {};
422
+ memAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
423
+ memAllocInfo.pNext = NULL;
424
+ memAllocInfo.allocationSize = 0;
425
+ memAllocInfo.memoryTypeIndex = 0;
426
+ return memAllocInfo;
427
+ }
428
+
429
+ VkCommandBufferAllocateInfo vkTools::initializers::commandBufferAllocateInfo(VkCommandPool commandPool, VkCommandBufferLevel level, uint32_t bufferCount)
430
+ {
431
+ VkCommandBufferAllocateInfo commandBufferAllocateInfo = {};
432
+ commandBufferAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
433
+ commandBufferAllocateInfo.commandPool = commandPool;
434
+ commandBufferAllocateInfo.level = level;
435
+ commandBufferAllocateInfo.commandBufferCount = bufferCount;
436
+ return commandBufferAllocateInfo;
437
+ }
438
+
439
+ VkCommandPoolCreateInfo vkTools::initializers::commandPoolCreateInfo()
440
+ {
441
+ VkCommandPoolCreateInfo cmdPoolCreateInfo = {};
442
+ cmdPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
443
+ return cmdPoolCreateInfo;
444
+ }
445
+
446
+ VkCommandBufferBeginInfo vkTools::initializers::commandBufferBeginInfo()
447
+ {
448
+ VkCommandBufferBeginInfo cmdBufferBeginInfo = {};
449
+ cmdBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
450
+ cmdBufferBeginInfo.pNext = NULL;
451
+ return cmdBufferBeginInfo;
452
+ }
453
+
454
+ VkCommandBufferInheritanceInfo vkTools::initializers::commandBufferInheritanceInfo()
455
+ {
456
+ VkCommandBufferInheritanceInfo cmdBufferInheritanceInfo = {};
457
+ cmdBufferInheritanceInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
458
+ return cmdBufferInheritanceInfo;
459
+ }
460
+
461
+ VkRenderPassBeginInfo vkTools::initializers::renderPassBeginInfo()
462
+ {
463
+ VkRenderPassBeginInfo renderPassBeginInfo = {};
464
+ renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
465
+ renderPassBeginInfo.pNext = NULL;
466
+ return renderPassBeginInfo;
467
+ }
468
+
469
+ VkRenderPassCreateInfo vkTools::initializers::renderPassCreateInfo()
470
+ {
471
+ VkRenderPassCreateInfo renderPassCreateInfo = {};
472
+ renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
473
+ renderPassCreateInfo.pNext = NULL;
474
+ return renderPassCreateInfo;
475
+ }
476
+
477
+ VkImageMemoryBarrier vkTools::initializers::imageMemoryBarrier()
478
+ {
479
+ VkImageMemoryBarrier imageMemoryBarrier = {};
480
+ imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
481
+ imageMemoryBarrier.pNext = NULL;
482
+ // Some default values
483
+ imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
484
+ imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
485
+ return imageMemoryBarrier;
486
+ }
487
+
488
+ VkBufferMemoryBarrier vkTools::initializers::bufferMemoryBarrier()
489
+ {
490
+ VkBufferMemoryBarrier bufferMemoryBarrier = {};
491
+ bufferMemoryBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
492
+ bufferMemoryBarrier.pNext = NULL;
493
+ return bufferMemoryBarrier;
494
+ }
495
+
496
+ VkMemoryBarrier vkTools::initializers::memoryBarrier()
497
+ {
498
+ VkMemoryBarrier memoryBarrier = {};
499
+ memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
500
+ memoryBarrier.pNext = NULL;
501
+ return memoryBarrier;
502
+ }
503
+
504
+ VkImageCreateInfo vkTools::initializers::imageCreateInfo()
505
+ {
506
+ VkImageCreateInfo imageCreateInfo = {};
507
+ imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
508
+ imageCreateInfo.pNext = NULL;
509
+ return imageCreateInfo;
510
+ }
511
+
512
+ VkSamplerCreateInfo vkTools::initializers::samplerCreateInfo()
513
+ {
514
+ VkSamplerCreateInfo samplerCreateInfo = {};
515
+ samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
516
+ samplerCreateInfo.pNext = NULL;
517
+ return samplerCreateInfo;
518
+ }
519
+
520
+ VkImageViewCreateInfo vkTools::initializers::imageViewCreateInfo()
521
+ {
522
+ VkImageViewCreateInfo imageViewCreateInfo = {};
523
+ imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
524
+ imageViewCreateInfo.pNext = NULL;
525
+ return imageViewCreateInfo;
526
+ }
527
+
528
+ VkFramebufferCreateInfo vkTools::initializers::framebufferCreateInfo()
529
+ {
530
+ VkFramebufferCreateInfo framebufferCreateInfo = {};
531
+ framebufferCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
532
+ framebufferCreateInfo.pNext = NULL;
533
+ return framebufferCreateInfo;
534
+ }
535
+
536
+ VkSemaphoreCreateInfo vkTools::initializers::semaphoreCreateInfo()
537
+ {
538
+ VkSemaphoreCreateInfo semaphoreCreateInfo = {};
539
+ semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
540
+ semaphoreCreateInfo.pNext = NULL;
541
+ semaphoreCreateInfo.flags = 0;
542
+ return semaphoreCreateInfo;
543
+ }
544
+
545
+ VkFenceCreateInfo vkTools::initializers::fenceCreateInfo(VkFenceCreateFlags flags)
546
+ {
547
+ VkFenceCreateInfo fenceCreateInfo = {};
548
+ fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
549
+ fenceCreateInfo.flags = flags;
550
+ return fenceCreateInfo;
551
+ }
552
+
553
+ VkEventCreateInfo vkTools::initializers::eventCreateInfo()
554
+ {
555
+ VkEventCreateInfo eventCreateInfo = {};
556
+ eventCreateInfo.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
557
+ return eventCreateInfo;
558
+ }
559
+
560
+ VkSubmitInfo vkTools::initializers::submitInfo()
561
+ {
562
+ VkSubmitInfo submitInfo = {};
563
+ submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
564
+ submitInfo.pNext = NULL;
565
+ return submitInfo;
566
+ }
567
+
568
+ VkViewport vkTools::initializers::viewport(
569
+ float width,
570
+ float height,
571
+ float minDepth,
572
+ float maxDepth)
573
+ {
574
+ VkViewport viewport = {};
575
+ viewport.width = width;
576
+ viewport.height = height;
577
+ viewport.minDepth = minDepth;
578
+ viewport.maxDepth = maxDepth;
579
+ return viewport;
580
+ }
581
+
582
+ VkRect2D vkTools::initializers::rect2D(
583
+ int32_t width,
584
+ int32_t height,
585
+ int32_t offsetX,
586
+ int32_t offsetY)
587
+ {
588
+ VkRect2D rect2D = {};
589
+ rect2D.extent.width = width;
590
+ rect2D.extent.height = height;
591
+ rect2D.offset.x = offsetX;
592
+ rect2D.offset.y = offsetY;
593
+ return rect2D;
594
+ }
595
+
596
+ VkBufferCreateInfo vkTools::initializers::bufferCreateInfo()
597
+ {
598
+ VkBufferCreateInfo bufCreateInfo = {};
599
+ bufCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
600
+ return bufCreateInfo;
601
+ }
602
+
603
+ VkBufferCreateInfo vkTools::initializers::bufferCreateInfo(
604
+ VkBufferUsageFlags usage,
605
+ VkDeviceSize size)
606
+ {
607
+ VkBufferCreateInfo bufCreateInfo = {};
608
+ bufCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
609
+ bufCreateInfo.pNext = NULL;
610
+ bufCreateInfo.usage = usage;
611
+ bufCreateInfo.size = size;
612
+ bufCreateInfo.flags = 0;
613
+ return bufCreateInfo;
614
+ }
615
+
616
+ VkDescriptorPoolCreateInfo vkTools::initializers::descriptorPoolCreateInfo(
617
+ uint32_t poolSizeCount,
618
+ VkDescriptorPoolSize* pPoolSizes,
619
+ uint32_t maxSets)
620
+ {
621
+ VkDescriptorPoolCreateInfo descriptorPoolInfo = {};
622
+ descriptorPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
623
+ descriptorPoolInfo.pNext = NULL;
624
+ descriptorPoolInfo.poolSizeCount = poolSizeCount;
625
+ descriptorPoolInfo.pPoolSizes = pPoolSizes;
626
+ descriptorPoolInfo.maxSets = maxSets;
627
+ return descriptorPoolInfo;
628
+ }
629
+
630
+ VkDescriptorPoolSize vkTools::initializers::descriptorPoolSize(
631
+ VkDescriptorType type,
632
+ uint32_t descriptorCount)
633
+ {
634
+ VkDescriptorPoolSize descriptorPoolSize = {};
635
+ descriptorPoolSize.type = type;
636
+ descriptorPoolSize.descriptorCount = descriptorCount;
637
+ return descriptorPoolSize;
638
+ }
639
+
640
+ VkDescriptorSetLayoutBinding vkTools::initializers::descriptorSetLayoutBinding(
641
+ VkDescriptorType type,
642
+ VkShaderStageFlags stageFlags,
643
+ uint32_t binding)
644
+ {
645
+ VkDescriptorSetLayoutBinding setLayoutBinding = {};
646
+ setLayoutBinding.descriptorType = type;
647
+ setLayoutBinding.stageFlags = stageFlags;
648
+ setLayoutBinding.binding = binding;
649
+ // Default value in all examples
650
+ setLayoutBinding.descriptorCount = 1;
651
+ return setLayoutBinding;
652
+ }
653
+
654
+ VkDescriptorSetLayoutCreateInfo vkTools::initializers::descriptorSetLayoutCreateInfo(
655
+ const VkDescriptorSetLayoutBinding* pBindings,
656
+ uint32_t bindingCount)
657
+ {
658
+ VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = {};
659
+ descriptorSetLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
660
+ descriptorSetLayoutCreateInfo.pNext = NULL;
661
+ descriptorSetLayoutCreateInfo.pBindings = pBindings;
662
+ descriptorSetLayoutCreateInfo.bindingCount = bindingCount;
663
+ return descriptorSetLayoutCreateInfo;
664
+ }
665
+
666
+ VkPipelineLayoutCreateInfo vkTools::initializers::pipelineLayoutCreateInfo(
667
+ const VkDescriptorSetLayout* pSetLayouts,
668
+ uint32_t setLayoutCount)
669
+ {
670
+ VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {};
671
+ pipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
672
+ pipelineLayoutCreateInfo.pNext = NULL;
673
+ pipelineLayoutCreateInfo.setLayoutCount = setLayoutCount;
674
+ pipelineLayoutCreateInfo.pSetLayouts = pSetLayouts;
675
+ return pipelineLayoutCreateInfo;
676
+ }
677
+
678
+ VkDescriptorSetAllocateInfo vkTools::initializers::descriptorSetAllocateInfo(
679
+ VkDescriptorPool descriptorPool,
680
+ const VkDescriptorSetLayout* pSetLayouts,
681
+ uint32_t descriptorSetCount)
682
+ {
683
+ VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = {};
684
+ descriptorSetAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
685
+ descriptorSetAllocateInfo.pNext = NULL;
686
+ descriptorSetAllocateInfo.descriptorPool = descriptorPool;
687
+ descriptorSetAllocateInfo.pSetLayouts = pSetLayouts;
688
+ descriptorSetAllocateInfo.descriptorSetCount = descriptorSetCount;
689
+ return descriptorSetAllocateInfo;
690
+ }
691
+
692
+ VkDescriptorImageInfo vkTools::initializers::descriptorImageInfo(VkSampler sampler, VkImageView imageView, VkImageLayout imageLayout)
693
+ {
694
+ VkDescriptorImageInfo descriptorImageInfo = {};
695
+ descriptorImageInfo.sampler = sampler;
696
+ descriptorImageInfo.imageView = imageView;
697
+ descriptorImageInfo.imageLayout = imageLayout;
698
+ return descriptorImageInfo;
699
+ }
700
+
701
+ VkWriteDescriptorSet vkTools::initializers::writeDescriptorSet(
702
+ VkDescriptorSet dstSet,
703
+ VkDescriptorType type,
704
+ uint32_t binding,
705
+ VkDescriptorBufferInfo* bufferInfo)
706
+ {
707
+ VkWriteDescriptorSet writeDescriptorSet = {};
708
+ writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
709
+ writeDescriptorSet.pNext = NULL;
710
+ writeDescriptorSet.dstSet = dstSet;
711
+ writeDescriptorSet.descriptorType = type;
712
+ writeDescriptorSet.dstBinding = binding;
713
+ writeDescriptorSet.pBufferInfo = bufferInfo;
714
+ // Default value in all examples
715
+ writeDescriptorSet.descriptorCount = 1;
716
+ return writeDescriptorSet;
717
+ }
718
+
719
+ VkWriteDescriptorSet vkTools::initializers::writeDescriptorSet(
720
+ VkDescriptorSet dstSet,
721
+ VkDescriptorType type,
722
+ uint32_t binding,
723
+ VkDescriptorImageInfo * imageInfo)
724
+ {
725
+ VkWriteDescriptorSet writeDescriptorSet = {};
726
+ writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
727
+ writeDescriptorSet.pNext = NULL;
728
+ writeDescriptorSet.dstSet = dstSet;
729
+ writeDescriptorSet.descriptorType = type;
730
+ writeDescriptorSet.dstBinding = binding;
731
+ writeDescriptorSet.pImageInfo = imageInfo;
732
+ // Default value in all examples
733
+ writeDescriptorSet.descriptorCount = 1;
734
+ return writeDescriptorSet;
735
+ }
736
+
737
+ VkVertexInputBindingDescription vkTools::initializers::vertexInputBindingDescription(
738
+ uint32_t binding,
739
+ uint32_t stride,
740
+ VkVertexInputRate inputRate)
741
+ {
742
+ VkVertexInputBindingDescription vInputBindDescription = {};
743
+ vInputBindDescription.binding = binding;
744
+ vInputBindDescription.stride = stride;
745
+ vInputBindDescription.inputRate = inputRate;
746
+ return vInputBindDescription;
747
+ }
748
+
749
+ VkVertexInputAttributeDescription vkTools::initializers::vertexInputAttributeDescription(
750
+ uint32_t binding,
751
+ uint32_t location,
752
+ VkFormat format,
753
+ uint32_t offset)
754
+ {
755
+ VkVertexInputAttributeDescription vInputAttribDescription = {};
756
+ vInputAttribDescription.location = location;
757
+ vInputAttribDescription.binding = binding;
758
+ vInputAttribDescription.format = format;
759
+ vInputAttribDescription.offset = offset;
760
+ return vInputAttribDescription;
761
+ }
762
+
763
+ VkPipelineVertexInputStateCreateInfo vkTools::initializers::pipelineVertexInputStateCreateInfo()
764
+ {
765
+ VkPipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo = {};
766
+ pipelineVertexInputStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
767
+ pipelineVertexInputStateCreateInfo.pNext = NULL;
768
+ return pipelineVertexInputStateCreateInfo;
769
+ }
770
+
771
+ VkPipelineInputAssemblyStateCreateInfo vkTools::initializers::pipelineInputAssemblyStateCreateInfo(
772
+ VkPrimitiveTopology topology,
773
+ VkPipelineInputAssemblyStateCreateFlags flags,
774
+ VkBool32 primitiveRestartEnable)
775
+ {
776
+ VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateCreateInfo = {};
777
+ pipelineInputAssemblyStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
778
+ pipelineInputAssemblyStateCreateInfo.topology = topology;
779
+ pipelineInputAssemblyStateCreateInfo.flags = flags;
780
+ pipelineInputAssemblyStateCreateInfo.primitiveRestartEnable = primitiveRestartEnable;
781
+ return pipelineInputAssemblyStateCreateInfo;
782
+ }
783
+
784
+ VkPipelineRasterizationStateCreateInfo vkTools::initializers::pipelineRasterizationStateCreateInfo(
785
+ VkPolygonMode polygonMode,
786
+ VkCullModeFlags cullMode,
787
+ VkFrontFace frontFace,
788
+ VkPipelineRasterizationStateCreateFlags flags)
789
+ {
790
+ VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateCreateInfo = {};
791
+ pipelineRasterizationStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
792
+ pipelineRasterizationStateCreateInfo.polygonMode = polygonMode;
793
+ pipelineRasterizationStateCreateInfo.cullMode = cullMode;
794
+ pipelineRasterizationStateCreateInfo.frontFace = frontFace;
795
+ pipelineRasterizationStateCreateInfo.flags = flags;
796
+ pipelineRasterizationStateCreateInfo.depthClampEnable = VK_TRUE;
797
+ pipelineRasterizationStateCreateInfo.lineWidth = 1.0f;
798
+ return pipelineRasterizationStateCreateInfo;
799
+ }
800
+
801
+ VkPipelineColorBlendAttachmentState vkTools::initializers::pipelineColorBlendAttachmentState(
802
+ VkColorComponentFlags colorWriteMask,
803
+ VkBool32 blendEnable)
804
+ {
805
+ VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState = {};
806
+ pipelineColorBlendAttachmentState.colorWriteMask = colorWriteMask;
807
+ pipelineColorBlendAttachmentState.blendEnable = blendEnable;
808
+ return pipelineColorBlendAttachmentState;
809
+ }
810
+
811
+ VkPipelineColorBlendStateCreateInfo vkTools::initializers::pipelineColorBlendStateCreateInfo(
812
+ uint32_t attachmentCount,
813
+ const VkPipelineColorBlendAttachmentState * pAttachments)
814
+ {
815
+ VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateCreateInfo = {};
816
+ pipelineColorBlendStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
817
+ pipelineColorBlendStateCreateInfo.pNext = NULL;
818
+ pipelineColorBlendStateCreateInfo.attachmentCount = attachmentCount;
819
+ pipelineColorBlendStateCreateInfo.pAttachments = pAttachments;
820
+ return pipelineColorBlendStateCreateInfo;
821
+ }
822
+
823
+ VkPipelineDepthStencilStateCreateInfo vkTools::initializers::pipelineDepthStencilStateCreateInfo(
824
+ VkBool32 depthTestEnable,
825
+ VkBool32 depthWriteEnable,
826
+ VkCompareOp depthCompareOp)
827
+ {
828
+ VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateCreateInfo = {};
829
+ pipelineDepthStencilStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
830
+ pipelineDepthStencilStateCreateInfo.depthTestEnable = depthTestEnable;
831
+ pipelineDepthStencilStateCreateInfo.depthWriteEnable = depthWriteEnable;
832
+ pipelineDepthStencilStateCreateInfo.depthCompareOp = depthCompareOp;
833
+ pipelineDepthStencilStateCreateInfo.front = pipelineDepthStencilStateCreateInfo.back;
834
+ pipelineDepthStencilStateCreateInfo.back.compareOp = VK_COMPARE_OP_ALWAYS;
835
+ return pipelineDepthStencilStateCreateInfo;
836
+ }
837
+
838
+ VkPipelineViewportStateCreateInfo vkTools::initializers::pipelineViewportStateCreateInfo(
839
+ uint32_t viewportCount,
840
+ uint32_t scissorCount,
841
+ VkPipelineViewportStateCreateFlags flags)
842
+ {
843
+ VkPipelineViewportStateCreateInfo pipelineViewportStateCreateInfo = {};
844
+ pipelineViewportStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
845
+ pipelineViewportStateCreateInfo.viewportCount = viewportCount;
846
+ pipelineViewportStateCreateInfo.scissorCount = scissorCount;
847
+ pipelineViewportStateCreateInfo.flags = flags;
848
+ return pipelineViewportStateCreateInfo;
849
+ }
850
+
851
+ VkPipelineMultisampleStateCreateInfo vkTools::initializers::pipelineMultisampleStateCreateInfo(
852
+ VkSampleCountFlagBits rasterizationSamples,
853
+ VkPipelineMultisampleStateCreateFlags flags)
854
+ {
855
+ VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateCreateInfo = {};
856
+ pipelineMultisampleStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
857
+ pipelineMultisampleStateCreateInfo.rasterizationSamples = rasterizationSamples;
858
+ pipelineMultisampleStateCreateInfo.flags = flags;
859
+ return pipelineMultisampleStateCreateInfo;
860
+ }
861
+
862
+ VkPipelineDynamicStateCreateInfo vkTools::initializers::pipelineDynamicStateCreateInfo(
863
+ const VkDynamicState * pDynamicStates,
864
+ uint32_t dynamicStateCount,
865
+ VkPipelineDynamicStateCreateFlags flags)
866
+ {
867
+ VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {};
868
+ pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
869
+ pipelineDynamicStateCreateInfo.pDynamicStates = pDynamicStates;
870
+ pipelineDynamicStateCreateInfo.dynamicStateCount = dynamicStateCount;
871
+ pipelineDynamicStateCreateInfo.flags = flags;
872
+ return pipelineDynamicStateCreateInfo;
873
+ }
874
+
875
+ VkPipelineTessellationStateCreateInfo vkTools::initializers::pipelineTessellationStateCreateInfo(uint32_t patchControlPoints)
876
+ {
877
+ VkPipelineTessellationStateCreateInfo pipelineTessellationStateCreateInfo = {};
878
+ pipelineTessellationStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
879
+ pipelineTessellationStateCreateInfo.patchControlPoints = patchControlPoints;
880
+ return pipelineTessellationStateCreateInfo;
881
+ }
882
+
883
+ VkGraphicsPipelineCreateInfo vkTools::initializers::pipelineCreateInfo(
884
+ VkPipelineLayout layout,
885
+ VkRenderPass renderPass,
886
+ VkPipelineCreateFlags flags)
887
+ {
888
+ VkGraphicsPipelineCreateInfo pipelineCreateInfo = {};
889
+ pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
890
+ pipelineCreateInfo.pNext = NULL;
891
+ pipelineCreateInfo.layout = layout;
892
+ pipelineCreateInfo.renderPass = renderPass;
893
+ pipelineCreateInfo.flags = flags;
894
+ return pipelineCreateInfo;
895
+ }
896
+
897
+ VkComputePipelineCreateInfo vkTools::initializers::computePipelineCreateInfo(VkPipelineLayout layout, VkPipelineCreateFlags flags)
898
+ {
899
+ VkComputePipelineCreateInfo computePipelineCreateInfo = {};
900
+ computePipelineCreateInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
901
+ computePipelineCreateInfo.layout = layout;
902
+ computePipelineCreateInfo.flags = flags;
903
+ return computePipelineCreateInfo;
904
+ }
905
+
906
+ VkPushConstantRange vkTools::initializers::pushConstantRange(
907
+ VkShaderStageFlags stageFlags,
908
+ uint32_t size,
909
+ uint32_t offset)
910
+ {
911
+ VkPushConstantRange pushConstantRange = {};
912
+ pushConstantRange.stageFlags = stageFlags;
913
+ pushConstantRange.offset = offset;
914
+ pushConstantRange.size = size;
915
+ return pushConstantRange;
916
+ }
917
+
918
+ // vi: set sw=2 ts=4 expandtab:
third_party/ktx-src/tests/loadtests/appfwSDL/VulkanAppSDL/vulkantools.h ADDED
@@ -0,0 +1,312 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright 2016 Sascha Willems - www.saschawillems.de
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * Assorted commonly used Vulkan helper functions
6
+ */
7
+
8
+ #pragma once
9
+
10
+ #include "vulkan/vulkan.h"
11
+
12
+ #include <math.h>
13
+ #include <stdlib.h>
14
+ #include <string>
15
+ #include <cstring>
16
+ #include <fstream>
17
+ #include <assert.h>
18
+ #include <stdio.h>
19
+ #include <vector>
20
+ #include <iostream>
21
+ #include <stdexcept>
22
+ #if defined(_WIN32)
23
+ #include <windows.h>
24
+ #include <fcntl.h>
25
+ #include <io.h>
26
+ #elif defined(__ANDROID__)
27
+ #include "vulkanandroid.h"
28
+ #include <android/asset_manager.h>
29
+ #endif
30
+
31
+ #include <SDL3/SDL_messagebox.h>
32
+
33
+ // Custom define for better code readability
34
+ #define VK_FLAGS_NONE 0
35
+ // Default fence timeout in nanoseconds
36
+ #define DEFAULT_FENCE_TIMEOUT 100000000000
37
+
38
+ #if 0
39
+ // Macro to check and display Vulkan return results
40
+ #define VK_CHECK_RESULT(f) \
41
+ { \
42
+ VkResult res = (f); \
43
+ if (res != VK_SUCCESS) \
44
+ { \
45
+ std::cout << "Fatal : VkResult is \"" << vkTools::errorString(res) << "\" in " << __FILE__ << " at line " << __LINE__ << std::endl; \
46
+ assert(res == VK_SUCCESS); \
47
+ } \
48
+ }
49
+ #endif
50
+ #if defined(DEBUG)
51
+ #include <sstream>
52
+ extern const char* appName();
53
+ #define VK_CHECK_RESULT(f) \
54
+ { \
55
+ VkResult res = (f); \
56
+ if (res != VK_SUCCESS) \
57
+ { \
58
+ std::stringstream msg; \
59
+ msg << "Fatal error. VkResult is \"" \
60
+ << vkTools::errorString(res) << "\" in " << __FILE__ \
61
+ << " at line " << __LINE__ << std::endl; \
62
+ SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, \
63
+ appName(), \
64
+ msg.str().c_str(), \
65
+ NULL); \
66
+ assert(res == VK_SUCCESS); \
67
+ } \
68
+ }
69
+ #else
70
+ #define VK_CHECK_RESULT(f) (void)f
71
+ #endif
72
+
73
+
74
+ namespace vkTools
75
+ {
76
+ // Check if extension is globally available
77
+ VkBool32 checkGlobalExtensionPresent(const char* extensionName);
78
+ // Check if extension is present on the given device
79
+ VkBool32 checkDeviceExtensionPresent(VkPhysicalDevice physicalDevice, const char* extensionName);
80
+ // Return string representation of a vulkan error string
81
+ std::string errorString(VkResult errorCode);
82
+
83
+ // Selected a suitable supported depth format starting with 32 bit down to 16 bit
84
+ // Returns false if none of the depth formats in the list is supported by the device
85
+ VkBool32 getSupportedDepthFormat(VkPhysicalDevice physicalDevice, VkFormat *depthFormat);
86
+
87
+ // Put an image memory barrier for setting an image layout on the sub resource into the given command buffer
88
+ void setImageLayout(
89
+ VkCommandBuffer cmdbuffer,
90
+ VkImage image,
91
+ VkImageAspectFlags aspectMask,
92
+ VkImageLayout oldImageLayout,
93
+ VkImageLayout newImageLayout,
94
+ VkImageSubresourceRange subresourceRange);
95
+ // Uses a fixed sub resource layout with first mip level and layer
96
+ void setImageLayout(
97
+ VkCommandBuffer cmdbuffer,
98
+ VkImage image,
99
+ VkImageAspectFlags aspectMask,
100
+ VkImageLayout oldImageLayout,
101
+ VkImageLayout newImageLayout);
102
+
103
+ // Display error message and exit on fatal error
104
+ void exitFatal(std::string message, std::string caption);
105
+ // Load a text file (e.g. GLGL shader) into a std::string
106
+ std::string readTextFile(const char *fileName);
107
+ // Load a binary file into a buffer (e.g. SPIR-V)
108
+ char *readBinaryFile(const char *filename, size_t *psize);
109
+
110
+ // Load a SPIR-V shader
111
+ #if defined(__ANDROID__)
112
+ VkShaderModule loadShader(AAssetManager* assetManager, const char *fileName, VkDevice device, VkShaderStageFlagBits stage);
113
+ #else
114
+ VkShaderModule loadShader(const char *fileName, VkDevice device, VkShaderStageFlagBits stage);
115
+ #endif
116
+
117
+ // Load a GLSL shader
118
+ // Note : Only for testing purposes, support for directly feeding GLSL shaders into Vulkan
119
+ // may be dropped at some point
120
+ VkShaderModule loadShaderGLSL(const char *fileName, VkDevice device, VkShaderStageFlagBits stage);
121
+
122
+ // Returns a pre-present image memory barrier
123
+ // Transforms the image's layout from color attachment to present khr
124
+ VkImageMemoryBarrier prePresentBarrier(VkImage presentImage);
125
+
126
+ // Returns a post-present image memory barrier
127
+ // Transforms the image's layout back from present khr to color attachment
128
+ VkImageMemoryBarrier postPresentBarrier(VkImage presentImage);
129
+
130
+ // Contains all vulkan objects
131
+ // required for a uniform data object
132
+ struct UniformData
133
+ {
134
+ VkBuffer buffer;
135
+ VkDeviceMemory memory;
136
+ VkDescriptorBufferInfo descriptor;
137
+ uint32_t allocSize;
138
+ void* mapped = nullptr;
139
+ };
140
+
141
+ // Destroy (and free) Vulkan resources used by a uniform data structure
142
+ void destroyUniformData(VkDevice device, vkTools::UniformData *uniformData);
143
+
144
+ // Contains often used vulkan object initializers
145
+ // Save lot of VK_STRUCTURE_TYPE assignments
146
+ // Some initializers are parameterized for convenience
147
+ namespace initializers
148
+ {
149
+ VkMemoryAllocateInfo memoryAllocateInfo();
150
+
151
+ VkCommandBufferAllocateInfo commandBufferAllocateInfo(
152
+ VkCommandPool commandPool,
153
+ VkCommandBufferLevel level,
154
+ uint32_t bufferCount);
155
+
156
+ VkCommandPoolCreateInfo commandPoolCreateInfo();
157
+ VkCommandBufferBeginInfo commandBufferBeginInfo();
158
+ VkCommandBufferInheritanceInfo commandBufferInheritanceInfo();
159
+
160
+ VkRenderPassBeginInfo renderPassBeginInfo();
161
+ VkRenderPassCreateInfo renderPassCreateInfo();
162
+
163
+ VkImageMemoryBarrier imageMemoryBarrier();
164
+ VkBufferMemoryBarrier bufferMemoryBarrier();
165
+ VkMemoryBarrier memoryBarrier();
166
+
167
+ VkImageCreateInfo imageCreateInfo();
168
+ VkSamplerCreateInfo samplerCreateInfo();
169
+ VkImageViewCreateInfo imageViewCreateInfo();
170
+
171
+ VkFramebufferCreateInfo framebufferCreateInfo();
172
+
173
+ VkSemaphoreCreateInfo semaphoreCreateInfo();
174
+ VkFenceCreateInfo fenceCreateInfo(VkFenceCreateFlags flags);
175
+ VkEventCreateInfo eventCreateInfo();
176
+
177
+ VkSubmitInfo submitInfo();
178
+
179
+ VkViewport viewport(
180
+ float width,
181
+ float height,
182
+ float minDepth,
183
+ float maxDepth);
184
+
185
+ VkRect2D rect2D(
186
+ int32_t width,
187
+ int32_t height,
188
+ int32_t offsetX,
189
+ int32_t offsetY);
190
+
191
+ VkBufferCreateInfo bufferCreateInfo();
192
+
193
+ VkBufferCreateInfo bufferCreateInfo(
194
+ VkBufferUsageFlags usage,
195
+ VkDeviceSize size);
196
+
197
+ VkDescriptorPoolCreateInfo descriptorPoolCreateInfo(
198
+ uint32_t poolSizeCount,
199
+ VkDescriptorPoolSize* pPoolSizes,
200
+ uint32_t maxSets);
201
+
202
+ VkDescriptorPoolSize descriptorPoolSize(
203
+ VkDescriptorType type,
204
+ uint32_t descriptorCount);
205
+
206
+ VkDescriptorSetLayoutBinding descriptorSetLayoutBinding(
207
+ VkDescriptorType type,
208
+ VkShaderStageFlags stageFlags,
209
+ uint32_t binding);
210
+
211
+ VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo(
212
+ const VkDescriptorSetLayoutBinding* pBindings,
213
+ uint32_t bindingCount);
214
+
215
+ VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo(
216
+ const VkDescriptorSetLayout* pSetLayouts,
217
+ uint32_t setLayoutCount );
218
+
219
+ VkDescriptorSetAllocateInfo descriptorSetAllocateInfo(
220
+ VkDescriptorPool descriptorPool,
221
+ const VkDescriptorSetLayout* pSetLayouts,
222
+ uint32_t descriptorSetCount);
223
+
224
+ VkDescriptorImageInfo descriptorImageInfo(
225
+ VkSampler sampler,
226
+ VkImageView imageView,
227
+ VkImageLayout imageLayout);
228
+
229
+ VkWriteDescriptorSet writeDescriptorSet(
230
+ VkDescriptorSet dstSet,
231
+ VkDescriptorType type,
232
+ uint32_t binding,
233
+ VkDescriptorBufferInfo* bufferInfo);
234
+
235
+ VkWriteDescriptorSet writeDescriptorSet(
236
+ VkDescriptorSet dstSet,
237
+ VkDescriptorType type,
238
+ uint32_t binding,
239
+ VkDescriptorImageInfo* imageInfo);
240
+
241
+ VkVertexInputBindingDescription vertexInputBindingDescription(
242
+ uint32_t binding,
243
+ uint32_t stride,
244
+ VkVertexInputRate inputRate);
245
+
246
+ VkVertexInputAttributeDescription vertexInputAttributeDescription(
247
+ uint32_t binding,
248
+ uint32_t location,
249
+ VkFormat format,
250
+ uint32_t offset);
251
+
252
+ VkPipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo();
253
+
254
+ VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateCreateInfo(
255
+ VkPrimitiveTopology topology,
256
+ VkPipelineInputAssemblyStateCreateFlags flags,
257
+ VkBool32 primitiveRestartEnable);
258
+
259
+ VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateCreateInfo(
260
+ VkPolygonMode polygonMode,
261
+ VkCullModeFlags cullMode,
262
+ VkFrontFace frontFace,
263
+ VkPipelineRasterizationStateCreateFlags flags);
264
+
265
+ VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState(
266
+ VkColorComponentFlags colorWriteMask,
267
+ VkBool32 blendEnable);
268
+
269
+ VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateCreateInfo(
270
+ uint32_t attachmentCount,
271
+ const VkPipelineColorBlendAttachmentState* pAttachments);
272
+
273
+ VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateCreateInfo(
274
+ VkBool32 depthTestEnable,
275
+ VkBool32 depthWriteEnable,
276
+ VkCompareOp depthCompareOp);
277
+
278
+ VkPipelineViewportStateCreateInfo pipelineViewportStateCreateInfo(
279
+ uint32_t viewportCount,
280
+ uint32_t scissorCount,
281
+ VkPipelineViewportStateCreateFlags flags);
282
+
283
+ VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateCreateInfo(
284
+ VkSampleCountFlagBits rasterizationSamples,
285
+ VkPipelineMultisampleStateCreateFlags flags);
286
+
287
+ VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo(
288
+ const VkDynamicState *pDynamicStates,
289
+ uint32_t dynamicStateCount,
290
+ VkPipelineDynamicStateCreateFlags flags);
291
+
292
+ VkPipelineTessellationStateCreateInfo pipelineTessellationStateCreateInfo(
293
+ uint32_t patchControlPoints);
294
+
295
+ VkGraphicsPipelineCreateInfo pipelineCreateInfo(
296
+ VkPipelineLayout layout,
297
+ VkRenderPass renderPass,
298
+ VkPipelineCreateFlags flags);
299
+
300
+ VkComputePipelineCreateInfo computePipelineCreateInfo(
301
+ VkPipelineLayout layout,
302
+ VkPipelineCreateFlags flags);
303
+
304
+ VkPushConstantRange pushConstantRange(
305
+ VkShaderStageFlags stageFlags,
306
+ uint32_t size,
307
+ uint32_t offset);
308
+ }
309
+
310
+ }
311
+
312
+ // vi: set sw=2 ts=4 expandtab:
third_party/ktx-src/tests/loadtests/appfwSDL/main.cpp ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* -*- tab-width: 4; -*- */
2
+ /* vi: set sw=2 ts=4 expandtab: */
3
+
4
+ /* $Id: f63e0a9e6eed51ed84a8eea1eff0708c8a6af22b $ */
5
+
6
+ /*
7
+ * Copyright 2015-2020 Mark Callow.
8
+ * SPDX-License-Identifier: Apache-2.0
9
+ */
10
+
11
+ /**
12
+ * @internal
13
+ * @file
14
+ * @~English
15
+ *
16
+ * @brief main() function for SDL app framework.
17
+ */
18
+
19
+ #include <string>
20
+ #include <vector>
21
+ #include <stdio.h>
22
+ #include "AppBaseSDL.h"
23
+ #include <SDL3/SDL_main.h>
24
+ #include "platform_utils.h"
25
+ #if defined(EMSCRIPTEN)
26
+ #include <emscripten.h>
27
+ #endif
28
+
29
+ #define SDL_GESTURE_IMPLEMENTATION 1
30
+ #include "SDL_gesture.h"
31
+
32
+ #if defined(SDL_PLATFORM_IOS)
33
+ #define NEED_MAIN_LOOP 0
34
+ //int SDL_iPhoneSetAnimationCallback(
35
+ // SDL_Window * window, int interval,
36
+ // void (*callback)(void*), void *callbackParam
37
+ // );
38
+ #define setAnimationCallback(win, cb, userdata) \
39
+ SDL_SetiOSAnimationCallback(win, 1, cb, userdata)
40
+ #elif defined(EMSCRIPTEN)
41
+ #define NEED_MAIN_LOOP 0
42
+ //void emscripten_set_main_loop_arg(em_arg_callback_func func, void *arg,
43
+ // int fps, int simulate_infinite_loop);
44
+ #define setAnimationCallback(win, cb, userdata) \
45
+ emscripten_set_main_loop_arg(cb, userdata, 0, 0)
46
+ #else
47
+ #define NEED_MAIN_LOOP 1
48
+ #define setAnimationCallback(win, cb, userdata)
49
+ #endif
50
+
51
+ static void
52
+ quit() {
53
+ Gesture_Quit();
54
+ SDL_Quit();
55
+ }
56
+
57
+ int
58
+ main(int argc, char* argv[])
59
+ {
60
+ if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS)) {
61
+ fprintf(stderr, "%s: SDL video initialization failed: %s\n",
62
+ theApp->name(), SDL_GetError());
63
+ return 1;
64
+ }
65
+ Gesture_Init();
66
+ atexit(quit);
67
+
68
+ InitUTF8CLI(argc, argv);
69
+ AppBaseSDL::Args args(argv, argv+argc);
70
+
71
+ if (!theApp->initialize(args))
72
+ return 1;
73
+
74
+ // Catches events before they are added to the event queue.
75
+ // May need this for some events that need rapid response...
76
+ // SDL_SetEventFilter(theApp->onEvent, theApp);
77
+ // Triggered when event added to queue.
78
+ SDL_AddEventWatch(theApp->onEvent, theApp);
79
+ if (!NEED_MAIN_LOOP) {
80
+ // TODO: Fix this main to work for multiple windows. One way is to have the
81
+ // application call setAnimationCallback and keep a list of the windows in
82
+ // this file, calling drawFrame for each window.
83
+ setAnimationCallback(theApp->getMainWindow(), theApp->onDrawFrame, theApp);
84
+ // iOS version of SDL will not exit when main completes.
85
+ // The Emscripten version of the app must be compiled with
86
+ // -s NO_EXIT_RUNTIME=1 to prevent Emscripten exiting when main completes.
87
+ return 0;
88
+ } else {
89
+ for (;;) {
90
+ SDL_PumpEvents();
91
+ theApp->drawFrame();
92
+ // XXX Let app return a sleeptime from drawFrame()? If so
93
+ // sleep(sleeptime);
94
+ }
95
+ }
96
+ }
third_party/ktx-src/tests/loadtests/common/LoadTestSample.cpp ADDED
@@ -0,0 +1,330 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* -*- tab-width: 4; -*- */
2
+ /* vi: set sw=2 ts=4 expandtab: */
3
+
4
+ /*
5
+ * Copyright 2017-2020 Mark Callow.
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+
9
+ /**
10
+ * @internal
11
+ * @class LoadTestSample
12
+ * @~English
13
+ *
14
+ * @brief Definition of a base class for texture loading test samples.
15
+ *
16
+ * @author Mark Callow, github.com/MarkCallow.
17
+ */
18
+
19
+ #if defined(_WIN32)
20
+ #define _USE_MATH_DEFINES
21
+ #endif
22
+ #include "LoadTestSample.h"
23
+ #define GLM_ENABLE_EXPERIMENTAL
24
+ #include <glm/gtx/vector_angle.hpp>
25
+ #include <SDL3/SDL_log.h>
26
+
27
+ #if !defined(LOADTESTSAMPLE_LOG_GESTURE_DETECTION)
28
+ // Log detected and completed gestures.
29
+ #define LOADTESTSAMPLE_LOG_GESTURE_DETECTION 0
30
+ #endif
31
+ #if !defined(LOADTESTSAMPLE_LOG_GESTURE_EVENTS)
32
+ // Log events contributing to gesture detection and gestures.
33
+ #define LOADTESTSAMPLE_LOG_GESTURE_EVENTS 0
34
+ #endif
35
+ #if !defined(LOADTESTSAMPLE_LOG_MOUSE_UP_DOWN_EVENTS)
36
+ #define LOADTESTSAMPLE_LOG_MOUSE_UP_DOWN_EVENTS 0
37
+ #endif
38
+ #if !defined(LOADTESTSAMPLE_LOG_MOUSE_MOTION_EVENTS)
39
+ #define LOADTESTSAMPLE_LOG_MOUSE_MOTION_EVENTS 0
40
+ #endif
41
+
42
+ #if LOADTESTSAMPLE_LOG_GESTURE_EVENTS
43
+ #include <sstream>
44
+
45
+ const std::string printFingerIds(SDL_Finger* fingers[], uint32_t numFingers) {
46
+ std::stringstream msg;
47
+ assert(numFingers > 0);
48
+ msg << std::hex << std::showbase;
49
+ msg << "finger id" << (numFingers > 1 ? "s" : "") << ": ";
50
+ for (uint32_t f = 0; f < numFingers; f++) {
51
+ if (f > 0) {
52
+ if (f == numFingers - 1)
53
+ msg << " & ";
54
+ else
55
+ msg << ", ";
56
+ }
57
+ msg << fingers[f]->id;
58
+ }
59
+ return msg.str();
60
+ }
61
+
62
+ const std::string printVector(const std::string& name, glm::vec2 v) {
63
+ std::stringstream msg;
64
+ msg << name << " (" << v.x << ", " << v.y << ")";
65
+ return msg.str();
66
+ }
67
+ #endif
68
+
69
+ [[maybe_unused]] static const char*
70
+ buttonName(Uint8 button) {
71
+ switch(button) {
72
+ case SDL_BUTTON_LEFT: return "left";
73
+ case SDL_BUTTON_MIDDLE: return "middle";
74
+ case SDL_BUTTON_RIGHT: return "right";
75
+ default: return "other";
76
+ }
77
+ }
78
+
79
+ int
80
+ LoadTestSample::doEvent(SDL_Event* event)
81
+ {
82
+ switch (event->type) {
83
+ case SDL_EVENT_MOUSE_MOTION:
84
+ {
85
+ SDL_MouseMotionEvent& motion = event->motion;
86
+ #if LOADTESTSAMPLE_LOG_MOUSE_MOTION_EVENTS
87
+ SDL_Log("LTS: MOUSE_MOTION - x: %f, y: %f", motion.x, motion.y);
88
+ #endif
89
+ // On macOS with trackpad, SDL_TOUCH_MOUSEID is never set.
90
+ // Prefer mouse events on macOS because press is required. When
91
+ // finger motion events are used the object starts to rotate when
92
+ // you drag the cursor over the window. Not nice.
93
+ if (mouseButtons.left)
94
+ {
95
+ rotation.x -= yflip * (mousePos.y - (float)motion.y) * 1.25f;
96
+ rotation.y -= (mousePos.x - (float)motion.x) * 1.25f;
97
+ viewChanged();
98
+ }
99
+ if (mouseButtons.right)
100
+ {
101
+ zoom += (mousePos.y - (float)motion.y) * .005f;
102
+ viewChanged();
103
+ }
104
+ if (mouseButtons.middle)
105
+ {
106
+ cameraPos.x -= (mousePos.x - (float)motion.x) * 0.01f;
107
+ cameraPos.y += yflip * (mousePos.y - (float)motion.y) * 0.01f;
108
+ viewChanged();
109
+ }
110
+ mousePos = glm::vec2((float)motion.x, (float)motion.y);
111
+ return 0;
112
+ }
113
+ case SDL_EVENT_MOUSE_BUTTON_DOWN:
114
+ mousePos = glm::vec2((float)event->button.x, (float)event->button.y);
115
+ if (LOADTESTSAMPLE_LOG_MOUSE_UP_DOWN_EVENTS) {
116
+ SDL_Log("LTS: MOUSE_DOWN - button: %s, x: %f, y: %f", buttonName(event->button.button),
117
+ event->button.x, event->button.y);
118
+ }
119
+ switch (event->button.button) {
120
+ case SDL_BUTTON_LEFT:
121
+ mouseButtons.left = true;
122
+ break;
123
+ case SDL_BUTTON_MIDDLE:
124
+ mouseButtons.middle = true;
125
+ break;
126
+ case SDL_BUTTON_RIGHT:
127
+ mouseButtons.right = true;
128
+ break;
129
+ default:
130
+ return 1;
131
+ }
132
+ return 0;
133
+ case SDL_EVENT_MOUSE_BUTTON_UP:
134
+ if (LOADTESTSAMPLE_LOG_MOUSE_UP_DOWN_EVENTS) {
135
+ SDL_Log("LTS: MOUSE_UP - button: %s, x: %f, y: %f", buttonName(event->button.button),
136
+ event->button.x, event->button.y);
137
+ }
138
+ switch (event->button.button) {
139
+ case SDL_BUTTON_LEFT:
140
+ mouseButtons.left = false;
141
+ break;
142
+ case SDL_BUTTON_MIDDLE:
143
+ mouseButtons.middle = false;
144
+ break;
145
+ case SDL_BUTTON_RIGHT:
146
+ mouseButtons.right = false;
147
+ break;
148
+ default:
149
+ return 1;
150
+ }
151
+ return 0;
152
+ case SDL_EVENT_FINGER_DOWN: {
153
+ // Prevent multifingers from triggering the left button action and
154
+ // interfering with multigestures.
155
+ //
156
+ // On iOS you get a left button down event no matter how many fingers
157
+ // you touch to the screen. We want 1 finger mouse to work so
158
+ // behaviour is same as pressing the trackpad on macOS, etc. As iOS
159
+ // button_down events come before finger_down we can clear the left
160
+ // button down state, if we have multiple fingers. Hope this ordering
161
+ // is the same on other touch screen platforms that send a left-button
162
+ // event regardless of the number of fingers.
163
+ //
164
+ // On macOS button_down events come after finger_down so this code has
165
+ // no effect.
166
+ //
167
+ // Another way to handle this is to identify the platform and work
168
+ // differently for each platform.
169
+ int numFingers;
170
+ SDL_Finger** fingers = SDL_GetTouchFingers(event->tfinger.touchID, &numFingers);
171
+ int retVal = 0;
172
+ #if LOADTESTSAMPLE_LOG_GESTURE_EVENTS
173
+ SDL_Log("LTS: Finger: %#" SDL_PRIx64 " down - fingers: %i, %s, x: %f, y: %f",
174
+ event->tfinger.fingerID, numFingers,
175
+ printFingerIds(fingers, numFingers).c_str(),
176
+ event->tfinger.x, event->tfinger.y);
177
+ #endif
178
+ if (numFingers > 1) {
179
+ mouseButtons.left = false;
180
+ if (LOADTESTSAMPLE_LOG_GESTURE_EVENTS) {
181
+ SDL_Log("LTS: FINGER_DOWN with multiple fingers received."
182
+ " Resetting mouseButtons.left.");
183
+ }
184
+ if (numFingers == 2) {
185
+ firstFingerId = fingers[0]->id;
186
+ // Calc. difference vector between fingers.
187
+ glm::vec2 vDifference;
188
+ vDifference.x = fingers[1]->x - fingers[0]->x;
189
+ vDifference.y = fingers[1]->y - fingers[0]->y;
190
+ distanceStart = glm::length(vDifference);
191
+ distanceLast = distanceStart;
192
+ // Need normalized vectors for glm::orientedAngle
193
+ nvDifferenceStart = glm::normalize(vDifference);
194
+ nvDifferenceLast = nvDifferenceStart;
195
+ processingGesture = true;
196
+ #if LOADTESTSAMPLE_LOG_GESTURE_EVENTS
197
+ // Angle of vector to X axis.
198
+ xAngleStart = atan2f(vDifference.y, vDifference.x);
199
+ SDL_Log("LTS: FINGER_DOWN, start values: %s, Distance = %f, XAngle = %f°",
200
+ printVector("Difference", vDifference).c_str(),
201
+ distanceStart, xAngleStart * 180.0 / M_PI
202
+ );
203
+ #endif
204
+ retVal = 1;
205
+ }
206
+ }
207
+
208
+ // It is possible to somehow get out of the window without seeing
209
+ // FINGER_UP so as a safeguard stop any previous gesture.
210
+ zooming = rotating = false;
211
+ SDL_free(fingers);
212
+ return retVal;
213
+ }
214
+ case SDL_EVENT_FINGER_UP: {
215
+ int numFingers;
216
+ SDL_Finger** fingers = SDL_GetTouchFingers(event->tfinger.touchID, &numFingers);
217
+ #if LOADTESTSAMPLE_LOG_GESTURE_EVENTS
218
+ SDL_Log("LTS: Finger: %#" SDL_PRIx64 " up - fingers: %i, %s, x: %f, y: %f",
219
+ event->tfinger.fingerID, numFingers,
220
+ printFingerIds(fingers, numFingers).c_str(),
221
+ event->tfinger.x, event->tfinger.y);
222
+ #endif
223
+ if (processingGesture && numFingers == 2) {
224
+ // There may still be one finger down. Even so the action is completed.
225
+ if (LOADTESTSAMPLE_LOG_GESTURE_DETECTION) {
226
+ SDL_Log("-------------- LTS: %s complete. -----------------",
227
+ zooming ? "zooming" : rotating ? "rotating" : "gesture");
228
+ }
229
+ zooming = rotating = processingGesture = false;
230
+ }
231
+ SDL_free(fingers);
232
+ break;
233
+ }
234
+ case SDL_EVENT_FINGER_MOTION: {
235
+ int numFingers;
236
+ SDL_Finger** fingers = SDL_GetTouchFingers(event->tfinger.touchID, &numFingers);
237
+ if (numFingers != 2)
238
+ return 1;
239
+ if (!processingGesture) {
240
+ // Protect against FINGER_MOTION without FINGER_DOWN. This can
241
+ // happen when the sample is switched by a swipe and the new sample
242
+ // receives the tail end of the swipe motion.
243
+ return 1;
244
+ }
245
+ // With two fingers down, events come in pairs. No point in processing
246
+ // both.
247
+ if (event->tfinger.fingerID == firstFingerId) {
248
+ return 0;
249
+ }
250
+
251
+ glm::vec2 vDifference; // Difference vector between the fingers.
252
+ vDifference.x = fingers[1]->x - fingers[0]->x;
253
+ vDifference.y = fingers[1]->y - fingers[0]->y;
254
+ float distance = glm::length(vDifference);
255
+ // Normalized vectors required by glm::orientedAngle
256
+ glm::vec2 nvDifference = glm::normalize(vDifference);
257
+ // Angle between start and current difference vectors
258
+ float sAngle = glm::orientedAngle(nvDifferenceStart, nvDifference);
259
+ // Angle between current and previous difference vectors
260
+ float dAngle = glm::orientedAngle(nvDifferenceLast, nvDifference);
261
+ // Difference in distance since last motion event.
262
+ float dDist = distance - distanceLast;
263
+ // Difference in distance since start.
264
+ float dDistStart = distance - distanceStart;
265
+ #if LOADTESTSAMPLE_LOG_GESTURE_EVENTS
266
+ if (!(rotating || zooming)) {
267
+ // Angle from X axis to vDifference vector
268
+ float xAngle = atan2f(vDifference.y, vDifference.x);
269
+ SDL_Log("LTS FINGER_MOTION: Not zooming or rotating. "
270
+ " timestamp = %" SDL_PRIu64 ", %s, %s",
271
+ event->tfinger.timestamp,
272
+ printFingerIds(fingers, numFingers).c_str(),
273
+ printVector("Difference", vDifference).c_str());
274
+ SDL_Log("... distanceLast = %f, distance = %f, dDist = %f, dDistStart = %f, xAngle = %f°, sAngle = %f°, dAngle = %f°",
275
+ distanceLast, distance, dDist, dDistStart,
276
+ xAngle * 180.0 / M_PI, sAngle * 180.0 / M_PI, dAngle * 180.0 / M_PI);
277
+ }
278
+ #endif
279
+ nvDifferenceLast = nvDifference;
280
+ distanceLast = distance;
281
+
282
+ // This is all heuristics derived from use.
283
+ if (zooming) {
284
+ zoom += dDist * 10.0f;
285
+ if (LOADTESTSAMPLE_LOG_GESTURE_EVENTS) {
286
+ SDL_Log("LTS MG: Zooming. zoom = %f", zoom);
287
+ }
288
+ } else if (!rotating) {
289
+ if (fabs(dDistStart) >= 0.1 && fabs(dAngle) < 0.5 * M_PI / 180.0) {
290
+ zooming = true;
291
+ zoom += dDist * 10.0f;
292
+ if (LOADTESTSAMPLE_LOG_GESTURE_DETECTION) {
293
+ SDL_Log("---------------- LTS MG: pinch/zoom detected ---------------\n"
294
+ " dAngle = %f°, dDistStart = %f, dDist = %f, zoom = %f",
295
+ dAngle * 180.0 / M_PI, dDistStart, dDist, zoom);
296
+ }
297
+ }
298
+ }
299
+ if (rotating) {
300
+ rotation.z +=
301
+ static_cast<float>(dAngle * 180.0 / M_PI);
302
+ if (LOADTESTSAMPLE_LOG_GESTURE_EVENTS) {
303
+ SDL_Log("LTS MG: Rotating around Z. rotation.z = %f°", rotation.z);
304
+ }
305
+ } else if (!zooming) {
306
+ if (fabs(sAngle) > 15 * M_PI / 180.0 && fabs(dDistStart) < 0.1) {
307
+ rotating = true;
308
+ rotation.z += static_cast<float>(dAngle * 180.0 / M_PI);
309
+ if (LOADTESTSAMPLE_LOG_GESTURE_DETECTION) {
310
+ SDL_Log("---------------- LTS MG: rotation detected ---------------\n"
311
+ " sAngle = %f°, dAngle = %f°, dDistStart = %f, rotation.z = %f°",
312
+ sAngle * 180 / M_PI, dAngle * 180.0 / M_PI, dDistStart, rotation.z);
313
+ }
314
+ }
315
+ }
316
+ viewChanged();
317
+ SDL_free(fingers);
318
+ return 0;
319
+ }
320
+ case SDL_EVENT_KEY_UP:
321
+ if (event->key.key == 'q')
322
+ quit = true;
323
+ keyPressed(event->key.key);
324
+ return 0;
325
+ default:
326
+ break;
327
+ }
328
+ return 1;
329
+ }
330
+
third_party/ktx-src/tests/loadtests/common/LoadTestSample.h ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* -*- tab-width: 4; -*- */
2
+ /* vi: set sw=2 ts=4 expandtab: */
3
+
4
+ /*
5
+ * Copyright 2017-2020 Mark Callow, <khronos at callow dot im>.
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+
9
+ #ifndef _LOAD_TEST_SAMPLE_H
10
+ #define _LOAD_TEST_SAMPLE_H
11
+
12
+ #include <string>
13
+ #include <SDL3/SDL.h>
14
+ #define GLM_FORCE_RADIANS
15
+ #include "disable_glm_warnings.h"
16
+ #include <glm/glm.hpp>
17
+ #include "reenable_warnings.h"
18
+
19
+ #define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
20
+
21
+ class LoadTestSample {
22
+ public:
23
+ typedef uint64_t ticks_t;
24
+ LoadTestSample(uint32_t width, uint32_t height,
25
+ const std::string sBasePath,
26
+ int32_t yflip = 1)
27
+ : w_width(width), w_height(height), yflip(yflip),
28
+ sBasePath(sBasePath)
29
+ {
30
+ }
31
+
32
+ virtual ~LoadTestSample() { };
33
+ virtual int doEvent(SDL_Event* event);
34
+ virtual void resize(uint32_t width, uint32_t height) = 0;
35
+ virtual void run(uint32_t msTicks) = 0;
36
+
37
+ //virtual void getOverlayText(TextOverlay *textOverlay) { };
38
+
39
+ typedef LoadTestSample* (*PFN_create)(uint32_t width, uint32_t height,
40
+ const char* const szArgs,
41
+ const std::string sBasePath);
42
+
43
+ protected:
44
+ virtual void keyPressed(uint32_t /*keyCode*/) { }
45
+ virtual void viewChanged() { }
46
+
47
+ const std::string getAssetPath() { return sBasePath; }
48
+
49
+ glm::vec3 rotation;
50
+ glm::vec3 cameraPos;
51
+ glm::vec2 mousePos;
52
+ glm::vec2 nvDifferenceStart; // Normalized difference between fingers at start of gesture.
53
+ float distanceStart = 0.0; // Distance between fingers at start of gesture.
54
+ float xAngleStart = 0.0; // Angle between x-axis and nvDifferenceStart. Unused unless event logging is enabled.
55
+ glm::vec2 nvDifferenceLast; // Normalized difference between fingers at last motion event.
56
+ float distanceLast = 0.0; // Distance between fingers at last motion event.
57
+ Uint64 firstFingerId = 0;
58
+ bool processingGesture = false;
59
+
60
+ struct {
61
+ bool left = false;
62
+ bool right = false;
63
+ bool middle = false;
64
+ } mouseButtons;
65
+ bool quit = false;
66
+ bool rotating = false;
67
+ bool zooming = false;
68
+ bool paused = false;
69
+
70
+ float zoom = 0;
71
+
72
+ uint32_t w_width;
73
+ uint32_t w_height;
74
+
75
+ // Defines a frame rate independent timer value clamped from -1.0...1.0
76
+ // For use in animations, rotations, etc.
77
+ float timer = 0.0f;
78
+ // Multiplier for speeding up (or slowing down) the global timer
79
+ float timerSpeed = 0.25f;
80
+
81
+ // Use to adjust mouse rotation speed
82
+ float rotationSpeed = 1.0f;
83
+ // Use to adjust mouse zoom speed
84
+ float zoomSpeed = 1.0f;
85
+ // multiplier to decide if Y increases down or up
86
+ int32_t yflip;
87
+
88
+ const std::string sBasePath;
89
+ };
90
+
91
+ #endif /* _LOAD_TEST_SAMPLE_H */
third_party/ktx-src/tests/loadtests/common/SwipeDetector.cpp ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* -*- tab-width: 4; -*- */
2
+ /* vi: set sw=2 ts=4 expandtab: */
3
+
4
+ /*
5
+ * Copyright 2017-2020 Mark Callow.
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+
9
+ /**
10
+ * @internal
11
+ * @class SwipeDetector
12
+ * @~English
13
+ *
14
+ * @brief Definition of a class for detecting swipes.
15
+ *
16
+ * @author Mark Callow, github.com/MarkCallow.
17
+ */
18
+
19
+ #include <assert.h>
20
+ #include "SwipeDetector.h"
21
+ #include <SDL3/SDL_log.h>
22
+
23
+ #if !defined(SWIPEDETECTOR_LOG_GESTURE_EVENTS)
24
+ #define SWIPEDETECTOR_LOG_GESTURE_EVENTS 0
25
+ #endif
26
+ #if !defined(SWIPEDETECTOR_LOG_GESTURE_DETECTION)
27
+ #define SWIPEDETECTOR_LOG_GESTURE_DETECTION 0
28
+ #endif
29
+
30
+ bool
31
+ SwipeDetector::doEvent(SDL_Event* event)
32
+ {
33
+ bool result = false;
34
+
35
+ switch (event->type) {
36
+ case SDL_EVENT_FINGER_UP: {
37
+ int numFingers;
38
+ SDL_Finger** fingers = SDL_GetTouchFingers(event->tfinger.touchID, &numFingers);
39
+ if (SWIPEDETECTOR_LOG_GESTURE_EVENTS) {
40
+ SDL_Log("SD: Finger: %" SDL_PRIx64 " UP - fingers: %i, x: %f, y: %f",
41
+ event->tfinger.fingerID, numFingers, event->tfinger.x, event->tfinger.y);
42
+ }
43
+ // SDL_GetTouchFingers appears to return the number of fingers
44
+ // down *before* the event was generated, so 1 means the last finger
45
+ // just lifted.
46
+ if (numFingers == 1 && gestureStart.time != 0) {
47
+ gestureStart.time = 0;
48
+ gestureSwipe = false;
49
+ if (SWIPEDETECTOR_LOG_GESTURE_DETECTION) {
50
+ SDL_Log("***************** SD: FINGER_UP, %smultigesture done *****************",
51
+ gestureSwipe ? "Swipe complete & " : "");
52
+ }
53
+ } else {
54
+ result = true;
55
+ }
56
+ SDL_free(fingers);
57
+ break;
58
+ }
59
+ case GESTURE_MULTIGESTURE: {
60
+ Gesture_MultiGestureEvent& mgesture = *(Gesture_MultiGestureEvent *)event;
61
+ if (SWIPEDETECTOR_LOG_GESTURE_EVENTS) {
62
+ SDL_Log("SD: MG Event: x = %f, y = %f, dAng = %f (%f), dR = %f, numFingers = %i, time = %" SDL_PRIu64,
63
+ mgesture.x,
64
+ mgesture.y,
65
+ mgesture.dTheta * 180.0 / M_PI,
66
+ mgesture.dTheta,
67
+ mgesture.dDist,
68
+ mgesture.numFingers,
69
+ mgesture.timestamp);
70
+ }
71
+ if (SWIPEDETECTOR_LOG_GESTURE_DETECTION) {
72
+ SDL_Log("SD: mgestureSwipe = %i, time = %" SDL_PRIu64,
73
+ gestureSwipe,
74
+ (mgesture.timestamp - gestureStart.time) / 1000000);
75
+ }
76
+ if (gestureStart.time == 0) {
77
+ if (SWIPEDETECTOR_LOG_GESTURE_DETECTION) {
78
+ SDL_Log("************ SD: Multigesture detection start **************");
79
+ }
80
+ gestureStart.time = mgesture.timestamp;
81
+ gestureStart.point.x = mgesture.x;
82
+ gestureStart.point.y = mgesture.y;
83
+ lastVector.reset();
84
+ gestureSwipe = false;
85
+ } else {
86
+ if (!gestureSwipe) {
87
+ vector sv; // Vector from start point to current position
88
+ float velocity;
89
+ float theta; // Angle between current vector and previous vector.
90
+ float duration;
91
+ sv.w = mgesture.x - gestureStart.point.x;
92
+ sv.h = mgesture.y - gestureStart.point.y;
93
+ float distance = sv.length();
94
+ if (lastVector.has_value()) {
95
+ // SDL2 timestamps were in milliseconds, SDL3 are nanoseconds. Given the
96
+ // normalized distances reported, using nanoseconds leads to 0 velocitySq.
97
+ duration = static_cast<float>(
98
+ (mgesture.timestamp - gestureStart.time) / 1000000.0);
99
+
100
+ velocity = distance / duration;
101
+ assert(!std::isinf(velocity));
102
+ theta = static_cast<float>(lastVector->getAngle(sv));
103
+ if (SWIPEDETECTOR_LOG_GESTURE_DETECTION) {
104
+ SDL_Log("SD: Detection: distance = %f, velocity = %f, theta = %f, sv angle = %f, sv angle normalized = %f, lastv angle = %f",
105
+ distance, velocity, theta,
106
+ sv.getAngle(),
107
+ sv.getAngleNormalized(),
108
+ lastVector->getAngle());
109
+ }
110
+ lastVector = sv;
111
+ // Multiple events with the same timestamp is a possibility
112
+ // hence the isinf() check.
113
+ if (std::abs(theta) < 3.0 && std::abs(mgesture.dDist) > 0.01 && !std::isinf(velocity) && velocity > 0.0007) {
114
+ if (SWIPEDETECTOR_LOG_GESTURE_DETECTION)
115
+ SDL_Log("----------------- SD: Swipe %s detected -----------------",
116
+ toString(sv.getDirection()).c_str());
117
+ gestureSwipe = true;
118
+ if (SDL_EventEnabled(SDL_EVENT_USER)) {
119
+ SDL_Event user_event;
120
+ // SDL will copy this entire struct! Initialize to keep memory
121
+ // checkers happy.
122
+ SDL_zero(user_event);
123
+ user_event.type = SDL_EVENT_USER;
124
+ user_event.user.code = swipeGesture;
125
+ user_event.user.data1 = SwipeDetector::directionToPointer(sv.getDirection());
126
+ user_event.user.data2 = NULL;
127
+ SDL_PushEvent(&user_event);
128
+ }
129
+ } else {
130
+ if (SWIPEDETECTOR_LOG_GESTURE_DETECTION) SDL_Log("SD: No swipe detected.");
131
+ result = true;
132
+ }
133
+ } else {
134
+ lastVector = sv;
135
+ result = true;
136
+ }
137
+ }
138
+ }
139
+ break;
140
+ }
141
+ default:
142
+ result = true;
143
+ }
144
+
145
+ return result;
146
+ }
third_party/ktx-src/tests/loadtests/common/SwipeDetector.h ADDED
@@ -0,0 +1,200 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* -*- tab-width: 4; -*- */
2
+ /* vi: set sw=2 ts=4 expandtab: */
3
+
4
+ /*
5
+ * Copyright 2017-2020 Mark Callow, <khronos at callow dot im>.
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+
9
+ #ifndef _SWIPE_DETECTOR_H
10
+ #define _SWIPE_DETECTOR_H
11
+ #if defined(_WIN32)
12
+ #define _USE_MATH_DEFINES
13
+ #endif
14
+ #include <optional>
15
+ #include <string>
16
+ #include <math.h>
17
+ #include <SDL3/SDL.h>
18
+ #include "SDL_gesture.h"
19
+
20
+ class SwipeDetector {
21
+ public:
22
+ enum class Direction { up, down, left, right };
23
+
24
+ SwipeDetector() : gestureSwipe(false) {}
25
+ bool doEvent(SDL_Event* event);
26
+
27
+ #if defined(_MSC_VER) && !defined(__clang__)
28
+ // Not clangcl
29
+ #pragma warning(push)
30
+ #pragma warning(disable : 4311)
31
+ #pragma warning(disable : 4302)
32
+ #pragma warning(disable : 4312)
33
+ #endif
34
+ #if defined(__clang__)
35
+ #pragma clang diagnostic push
36
+ #pragma clang diagnostic ignored "-Wvoid-pointer-to-int-cast"
37
+ #endif
38
+ // These conversions allow storing a Direction in a pointer.
39
+ // Ugly. Horrible. But preferable to allocating and freeing memory
40
+ // when passing the information in user events.
41
+ static inline Direction pointerToDirection(void* p) {
42
+ return static_cast<SwipeDetector::Direction>(reinterpret_cast<long>(p));
43
+ }
44
+
45
+ // Only preserves the low 32-bits of the pointer; perfect for this use.
46
+ static inline void* directionToPointer(SwipeDetector::Direction d) {
47
+ return reinterpret_cast<void*>(static_cast<long>(d));
48
+ }
49
+ #if defined(_MSC_VER) && !defined(__clang__)
50
+ #pragma warning(pop)
51
+ #endif
52
+ #if defined(__clang__)
53
+ #pragma clang diagnostic pop
54
+ #endif
55
+
56
+ static const Uint32 swipeGesture = 0x01;
57
+
58
+ class vector {
59
+ public:
60
+ float w;
61
+ float h;
62
+
63
+ vector() : w(0.0), h(0.0) { }
64
+ vector(float _w, float _h) : w(_w), h(_h) { }
65
+ /**
66
+ * @~English
67
+ * @internal
68
+ * @brief Find the angle between the vector and the X-axis
69
+ *
70
+ * Positive angles increase counter-clockwise from the X-axis
71
+ * which has +x to the right.
72
+ *
73
+ * @return the angle between the vector and the x axis in degrees.
74
+ */
75
+ double getAngle() {
76
+ double rad = atan2(h, w);
77
+ return rad * 180/M_PI;
78
+ }
79
+
80
+ /**
81
+ * @~English
82
+ * @internal
83
+ * @brief Find the angle between this vector and another.
84
+ *
85
+ * Positive angles increase counter-clockwise.
86
+ *
87
+ * @return the angle between the 2 vectors in degrees.
88
+ */
89
+ double getAngle(const vector& v2) {
90
+ // Reputed to be more accurate but in our use so far both approaches give same answer.
91
+ //double rad = atan2f(v2.h, v2.w) - SDL_atan2(h, w);
92
+ double rad = atan2f(w * v2.h - h * v2.w, w * v2.w + h * v2.h);
93
+ return rad * 180/M_PI;
94
+ }
95
+
96
+ /**
97
+ * @~English
98
+ * @internal
99
+ * @brief Find the angle between the vector and the X-axis
100
+ *
101
+ * Positive angles increase counter-clockwise from the X-axis
102
+ * which has +x to the right. Value is normalized to the range 0 to 360.
103
+ *
104
+ * @return the angle between the vector and the x axis in degrees.
105
+ */
106
+ double getAngleNormalized() {
107
+ double rad = atan2(h, w) + M_PI;
108
+ return fmod(rad*180/M_PI + 180, 360);
109
+ }
110
+
111
+ /**
112
+ * @~English
113
+ * @internal
114
+ * @brief Return the length of the vector.
115
+ *
116
+ * @return the length of the vector.
117
+ */
118
+ float length() { return sqrt(w * w + h * h); }
119
+
120
+ /**
121
+ * @~English
122
+ * @internal
123
+ * @brief Return the direction of the vector.
124
+ *
125
+ * @return the direction
126
+ */
127
+ Direction getDirection() {
128
+ double angle = getAngleNormalized();
129
+ return getDirection(angle);
130
+ }
131
+
132
+ /**
133
+ * @~English
134
+ * @internal
135
+ * @brief Return a direction given an angle.
136
+ *
137
+ * Directions are defined as follows:
138
+ *
139
+ * Up: [45, 135]
140
+ * Right: [0,45] and [315, 360]
141
+ * Down: [225, 315]
142
+ * Left: [135, 225]
143
+ *
144
+ * @param angle an angle from 0 to 360°
145
+ * @return the direction of an angle
146
+ */
147
+ static Direction getDirection(double angle){
148
+ if (inRange(angle, 45, 135)) {
149
+ return Direction::down;
150
+ } else if (inRange(angle, 0, 45) || inRange(angle, 315, 360)) {
151
+ return Direction::right;
152
+ } else if (inRange(angle, 225, 315)) {
153
+ return Direction::up;
154
+ } else {
155
+ return Direction::left;
156
+ }
157
+ }
158
+
159
+ protected:
160
+ /**
161
+ * @~English
162
+ * @internal
163
+ * @brief Check if angle falls within an interval.
164
+ *
165
+ * @param angle an angle
166
+ * @param init the initial bound
167
+ * @param end the final bound
168
+ *
169
+ * @return true if the given angle is in the interval [init, end), false
170
+ * otherwise.
171
+ */
172
+ static bool inRange(double angle, float init, float end){
173
+ return (angle >= init) && (angle < end);
174
+ }
175
+ };
176
+
177
+ protected:
178
+ struct gestureStart {
179
+ Uint64 time;
180
+ SDL_FPoint point;
181
+ gestureStart() { time = 0; point.x = point.y = 0.0; }
182
+ } gestureStart;
183
+ std::optional<vector> lastVector;
184
+ bool gestureSwipe;
185
+ };
186
+
187
+ [[nodiscard]] inline std::string toString(SwipeDetector::Direction dir) {
188
+ switch (dir) {
189
+ case SwipeDetector::Direction::up: return "up";
190
+ case SwipeDetector::Direction::down: return "down";
191
+ case SwipeDetector::Direction::left: return "left";
192
+ case SwipeDetector::Direction::right: return "right";
193
+ // This is to hide a warning from MSVC. According to the solution given
194
+ // in https://developercommunity.visualstudio.com/t/Visual-Studio-warning-on-Strongly-typed-/96302
195
+ // it is possible to construct an enum class with any value. Thus warning.
196
+ default: return "unknown";
197
+ }
198
+ }
199
+
200
+ #endif /* _SWIPE_DETECTOR_H */
third_party/ktx-src/tests/loadtests/common/TranscodeTargetStrToFmt.cpp ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* -*- tab-width: 4; -*- */
2
+ /* vi: set sw=2 ts=4 expandtab: */
3
+
4
+ /*
5
+ * Copyright 2017-2020 Mark Callow, <khronos at callow dot im>.
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+
9
+ #include <assert.h>
10
+ #include <ktx.h>
11
+ #include "TranscodeTargetStrToFmt.h"
12
+
13
+ ktx_transcode_fmt_e
14
+ TranscodeTargetStrToFmt(std::string format)
15
+ {
16
+ if (!format.compare("ETC1_RGB"))
17
+ return KTX_TTF_ETC1_RGB;
18
+ else if (!format.compare("ETC2_RGBA"))
19
+ return KTX_TTF_ETC2_RGBA;
20
+ else if (!format.compare("BC1_RGB"))
21
+ return KTX_TTF_BC1_RGB;
22
+ else if (!format.compare("BC3_RGBA"))
23
+ return KTX_TTF_BC3_RGBA;
24
+ else if (!format.compare("BC4_R"))
25
+ return KTX_TTF_BC4_R;
26
+ else if (!format.compare("BC5_RG"))
27
+ return KTX_TTF_BC5_RG;
28
+ else if (!format.compare("BC7_M6_RGB"))
29
+ return KTX_TTF_BC7_M6_RGB;
30
+ else if (!format.compare("BC7_M5_RGBA"))
31
+ return KTX_TTF_BC7_M5_RGBA;
32
+ else if (!format.compare("PVRTC1_4_RGB"))
33
+ return KTX_TTF_PVRTC1_4_RGB;
34
+ else if (!format.compare("PVRTC1_4_RGBA"))
35
+ return KTX_TTF_PVRTC1_4_RGBA;
36
+ else if (!format.compare("ASTC_4x4_RGBA"))
37
+ return KTX_TTF_ASTC_4x4_RGBA;
38
+ else if (!format.compare("PVRTC2_4_RGB"))
39
+ return KTX_TTF_PVRTC2_4_RGB;
40
+ else if (!format.compare("PVRTC2_4_RGBA"))
41
+ return KTX_TTF_PVRTC2_4_RGBA;
42
+ else if (!format.compare("ETC2_EAC_R11"))
43
+ return KTX_TTF_ETC2_EAC_R11;
44
+ else if (!format.compare("ETC2_EAC_RG11"))
45
+ return KTX_TTF_ETC2_EAC_RG11;
46
+ else if (!format.compare("RGBA32"))
47
+ return KTX_TTF_RGBA32;
48
+ else if (!format.compare("RGB565"))
49
+ return KTX_TTF_RGB565;
50
+ else if (!format.compare("BGR565"))
51
+ return KTX_TTF_BGR565;
52
+ else if (!format.compare("RGBA4444"))
53
+ return KTX_TTF_RGBA4444;
54
+ else if (!format.compare("ETC"))
55
+ return KTX_TTF_ETC;
56
+ else if (!format.compare("BC1_OR_3"))
57
+ return KTX_TTF_BC1_OR_3;
58
+ assert(false); // Error in args in sample table.
59
+ return static_cast<ktx_transcode_fmt_e>(-1); // To keep compilers happy.
60
+ }
61
+
third_party/ktx-src/tests/loadtests/common/TranscodeTargetStrToFmt.h ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* -*- tab-width: 4; -*- */
2
+ /* vi: set sw=2 ts=4 expandtab: */
3
+
4
+ /*
5
+ * Copyright 2017-2020 Mark Callow, <khronos at callow dot im>.
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+
9
+ #ifndef _TRANSCODE_TARGET_STR_TO_FMT_
10
+ #define _TRANSCODE_TARGET_STR_TO_FMT_
11
+
12
+ #include <string>
13
+
14
+ ktx_transcode_fmt_e TranscodeTargetStrToFmt(std::string format);
15
+
16
+ #endif /* _TRANSCODE_TARGET_STR_TO_FMT_ */
third_party/ktx-src/tests/loadtests/common/disable_glm_warnings.h ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* -*- tab-width: 4; -*- */
2
+ /* vi: set sw=2 ts=4 expandtab: */
3
+
4
+ /*
5
+ * Copyright 2021 Mark Callow.
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+
9
+ #if !defined DISABLE_GLM_WARNINGS_H
10
+
11
+ // Temporarily disable the warnings caused by the GLM code.
12
+ #if defined(_MSC_VER)
13
+ #pragma warning(push)
14
+ #pragma warning(disable: 4201)
15
+ #elif defined(__clang__)
16
+ #pragma clang diagnostic push
17
+ #pragma clang diagnostic ignored "-Wgnu-anonymous-struct"
18
+ #pragma clang diagnostic ignored "-Wnested-anon-types"
19
+ #endif
20
+
21
+ #endif /* DISABLE_GLM_WARNINGS_H */
third_party/ktx-src/tests/loadtests/common/ltexceptions.h ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* -*- tab-width: 4; -*- */
2
+ /* vi: set sw=2 ts=4 expandtab: */
3
+
4
+ /*
5
+ * Copyright 2018-2020 Mark Callow, <khronos at callow dot im>.
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+
9
+ /**
10
+ * @internal
11
+ * @file
12
+ * @~English
13
+ *
14
+ * @brief Custom exceptions for the load tests.
15
+ */
16
+
17
+ #include <stdexcept>
18
+ #include <string>
19
+
20
+ #define OUT_OF_HOST_MEMORY -1
21
+ #define OUT_OF_DEVICE_MEMORY -2
22
+ #define FRAGMENTED_POOL -12
23
+ #define OUT_OF_POOL_MEMORY -1000069000
24
+
25
+ class bad_vulkan_alloc : public std::bad_alloc {
26
+ public:
27
+ bad_vulkan_alloc(int which, const char* _message) : std::bad_alloc() {
28
+ if (which == FRAGMENTED_POOL) {
29
+ message << "Pool fragmented when allocating for " << _message << ".";
30
+ } else {
31
+ std::string memtype;
32
+ switch (which) {
33
+ case OUT_OF_HOST_MEMORY: memtype = "host"; break;
34
+ case OUT_OF_DEVICE_MEMORY: memtype = "device"; break;
35
+ case OUT_OF_POOL_MEMORY: memtype = "pool"; break;
36
+ default: break;
37
+ }
38
+ message << "Out of " << memtype << " memory for " << _message << ".";
39
+ }
40
+ _what = message.str();
41
+ }
42
+ bad_vulkan_alloc(const bad_vulkan_alloc& in)
43
+ : std::bad_alloc()
44
+ , message{in.message.str()}
45
+ , _what{in._what}
46
+ {}
47
+ virtual const char* what() const throw() {
48
+ return _what.c_str();
49
+ }
50
+ protected:
51
+ std::stringstream message;
52
+ std::string _what;
53
+ };
54
+
55
+ class unsupported_ttype : public std::runtime_error {
56
+ public:
57
+ unsupported_ttype()
58
+ : std::runtime_error("Implementation does not support needed operations on image format") { }
59
+ unsupported_ttype(std::string& message) : std::runtime_error(message) { }
60
+ };
61
+
62
+ class unsupported_ctype : public std::runtime_error {
63
+ public:
64
+ unsupported_ctype()
65
+ : std::runtime_error("Unsupported compression format") { }
66
+ };
third_party/ktx-src/tests/loadtests/common/models/cube.obj ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2020 The Khronos Group Inc.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ # Max2Obj Version 4.0 Mar 10th, 2001
5
+ #
6
+ # object default to come ...
7
+ #
8
+ v -5.000000 -5.000000 -5.000000
9
+ v 5.000000 -5.000000 -5.000000
10
+ v -5.000000 5.000000 -5.000000
11
+ v 5.000000 5.000000 -5.000000
12
+ v -5.000000 -5.000000 5.000000
13
+ v 5.000000 -5.000000 5.000000
14
+ v -5.000000 5.000000 5.000000
15
+ v 5.000000 5.000000 5.000000
16
+ # 8 vertices
17
+
18
+ vt 0.000000 0.000000 0.000000
19
+ vt 1.000000 0.000000 0.000000
20
+ vt 0.000000 1.000000 0.000000
21
+ vt 1.000000 1.000000 0.000000
22
+ vt 0.000000 0.000000 0.000000
23
+ vt 1.000000 0.000000 0.000000
24
+ vt 0.000000 1.000000 0.000000
25
+ vt 1.000000 1.000000 0.000000
26
+ vt 0.000000 0.000000 0.000000
27
+ vt 1.000000 0.000000 0.000000
28
+ vt 0.000000 1.000000 0.000000
29
+ vt 1.000000 1.000000 0.000000
30
+ # 12 texture vertices
31
+
32
+ vn 0.000000 0.000000 -2.000000
33
+ vn 0.000000 0.000000 -1.000000
34
+ vn 0.000000 0.000000 -1.000000
35
+ vn 0.000000 0.000000 -2.000000
36
+ vn 0.000000 -0.000000 2.000000
37
+ vn 0.000000 -0.000000 1.000000
38
+ vn 0.000000 -0.000000 1.000000
39
+ vn 0.000000 -0.000000 2.000000
40
+ # 8 vertex normals
41
+
42
+ g default
43
+ s 2
44
+ f 1/10/1 3/12/3 4/11/4
45
+ f 4/11/4 2/9/2 1/10/1
46
+ s 4
47
+ f 5/9/5 6/10/6 8/12/8
48
+ f 8/12/8 7/11/7 5/9/5
49
+ s 8
50
+ f 1/5/1 2/6/2 6/8/6
51
+ f 6/8/6 5/7/5 1/5/1
52
+ s 16
53
+ f 2/1/2 4/2/4 8/4/8
54
+ f 8/4/8 6/3/6 2/1/2
55
+ s 32
56
+ f 4/5/4 3/6/3 7/8/7
57
+ f 7/8/7 8/7/8 4/5/4
58
+ s 64
59
+ f 3/1/3 1/2/1 5/4/5
60
+ f 5/4/5 7/3/7 3/1/3
61
+ # 12 faces
62
+
63
+ g
third_party/ktx-src/tests/loadtests/common/models/sphere.obj ADDED
@@ -0,0 +1,2503 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2020 The Khronos Group Inc.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ # Max2Obj Version 4.0 Mar 10th, 2001
5
+ #
6
+ # object default to come ...
7
+ #
8
+ v 0.000000 19.737080 -0.000000
9
+ v -0.000000 19.357838 -3.850513
10
+ v -0.751198 19.357838 -3.776527
11
+ v -1.473528 19.357838 -3.557410
12
+ v -2.139230 19.357838 -3.201585
13
+ v -2.722724 19.357838 -2.722724
14
+ v -3.201585 19.357838 -2.139230
15
+ v -3.557411 19.357838 -1.473527
16
+ v -3.776527 19.357838 -0.751197
17
+ v -3.850513 19.357838 0.000001
18
+ v -3.776526 19.357838 0.751199
19
+ v -3.557410 19.357838 1.473529
20
+ v -3.201584 19.357838 2.139232
21
+ v -2.722722 19.357838 2.722726
22
+ v -2.139228 19.357838 3.201586
23
+ v -1.473525 19.357838 3.557412
24
+ v -0.751195 19.357838 3.776527
25
+ v 0.000004 19.357838 3.850513
26
+ v 0.751202 19.357838 3.776526
27
+ v 1.473532 19.357838 3.557409
28
+ v 2.139235 19.357838 3.201582
29
+ v 2.722728 19.357838 2.722721
30
+ v 3.201588 19.357838 2.139226
31
+ v 3.557413 19.357838 1.473523
32
+ v 3.776528 19.357838 0.751192
33
+ v 3.850513 19.357838 -0.000006
34
+ v 3.776525 19.357838 -0.751204
35
+ v 3.557408 19.357838 -1.473534
36
+ v 3.201581 19.357838 -2.139236
37
+ v 2.722719 19.357838 -2.722729
38
+ v 2.139224 19.357838 -3.201589
39
+ v 1.473520 19.357838 -3.557414
40
+ v 0.751190 19.357838 -3.776528
41
+ v -0.000000 18.234684 -7.553053
42
+ v -1.473528 18.234684 -7.407924
43
+ v -2.890428 18.234684 -6.978112
44
+ v -4.196251 18.234684 -6.280135
45
+ v -5.340816 18.234684 -5.340816
46
+ v -6.280135 18.234684 -4.196251
47
+ v -6.978112 18.234684 -2.890427
48
+ v -7.407924 18.234684 -1.473526
49
+ v -7.553053 18.234684 0.000002
50
+ v -7.407923 18.234684 1.473531
51
+ v -6.978110 18.234684 2.890432
52
+ v -6.280132 18.234684 4.196255
53
+ v -5.340812 18.234684 5.340819
54
+ v -4.196247 18.234684 6.280138
55
+ v -2.890423 18.234684 6.978114
56
+ v -1.473521 18.234684 7.407925
57
+ v 0.000007 18.234684 7.553053
58
+ v 1.473535 18.234684 7.407922
59
+ v 2.890436 18.234684 6.978108
60
+ v 4.196259 18.234684 6.280129
61
+ v 5.340822 18.234684 5.340808
62
+ v 6.280140 18.234684 4.196243
63
+ v 6.978116 18.234684 2.890418
64
+ v 7.407926 18.234684 1.473516
65
+ v 7.553053 18.234684 -0.000012
66
+ v 7.407921 18.234684 -1.473540
67
+ v 6.978106 18.234684 -2.890441
68
+ v 6.280127 18.234684 -4.196263
69
+ v 5.340805 18.234684 -5.340826
70
+ v 4.196239 18.234684 -6.280143
71
+ v 2.890414 18.234684 -6.978117
72
+ v 1.473512 18.234684 -7.407927
73
+ v -0.000000 16.410782 -10.965334
74
+ v -2.139230 16.410782 -10.754638
75
+ v -4.196251 16.410782 -10.130648
76
+ v -6.092012 16.410782 -9.117342
77
+ v -7.753662 16.410782 -7.753662
78
+ v -9.117343 16.410782 -6.092012
79
+ v -10.130649 16.410782 -4.196250
80
+ v -10.754639 16.410782 -2.139228
81
+ v -10.965334 16.410782 0.000004
82
+ v -10.754638 16.410782 2.139235
83
+ v -10.130646 16.410782 4.196257
84
+ v -9.117338 16.410782 6.092018
85
+ v -7.753657 16.410782 7.753667
86
+ v -6.092007 16.410782 9.117347
87
+ v -4.196243 16.410782 10.130651
88
+ v -2.139221 16.410782 10.754640
89
+ v 0.000011 16.410782 10.965334
90
+ v 2.139242 16.410782 10.754636
91
+ v 4.196263 16.410782 10.130643
92
+ v 6.092024 16.410782 9.117334
93
+ v 7.753672 16.410782 7.753652
94
+ v 9.117351 16.410782 6.092000
95
+ v 10.130653 16.410782 4.196237
96
+ v 10.754642 16.410782 2.139214
97
+ v 10.965334 16.410782 -0.000018
98
+ v 10.754635 16.410782 -2.139249
99
+ v 10.130640 16.410782 -4.196270
100
+ v 9.117331 16.410782 -6.092030
101
+ v 7.753647 16.410782 -7.753677
102
+ v 6.091995 16.410782 -9.117354
103
+ v 4.196230 16.410782 -10.130656
104
+ v 2.139207 16.410782 -10.754642
105
+ v -0.000001 13.956223 -13.956223
106
+ v -2.722724 13.956223 -13.688058
107
+ v -5.340815 13.956223 -12.893869
108
+ v -7.753661 13.956223 -11.604176
109
+ v -9.868540 13.956223 -9.868540
110
+ v -11.604177 13.956223 -7.753661
111
+ v -12.893869 13.956223 -5.340813
112
+ v -13.688059 13.956223 -2.722721
113
+ v -13.956223 13.956223 0.000005
114
+ v -13.688057 13.956223 2.722730
115
+ v -12.893867 13.956223 5.340822
116
+ v -11.604171 13.956223 7.753669
117
+ v -9.868534 13.956223 9.868546
118
+ v -7.753654 13.956223 11.604181
119
+ v -5.340805 13.956223 12.893873
120
+ v -2.722712 13.956223 13.688061
121
+ v 0.000013 13.956223 13.956223
122
+ v 2.722738 13.956223 13.688055
123
+ v 5.340830 13.956223 12.893863
124
+ v 7.753676 13.956223 11.604166
125
+ v 9.868553 13.956223 9.868527
126
+ v 11.604186 13.956223 7.753646
127
+ v 12.893877 13.956223 5.340797
128
+ v 13.688063 13.956223 2.722703
129
+ v 13.956223 13.956223 -0.000022
130
+ v 13.688054 13.956223 -2.722747
131
+ v 12.893860 13.956223 -5.340838
132
+ v 11.604161 13.956223 -7.753684
133
+ v 9.868521 13.956223 -9.868559
134
+ v 7.753639 13.956223 -11.604191
135
+ v 5.340788 13.956223 -12.893880
136
+ v 2.722694 13.956223 -13.688065
137
+ v -0.000001 10.965333 -16.410782
138
+ v -3.201585 10.965333 -16.095453
139
+ v -6.280134 10.965333 -15.161586
140
+ v -9.117341 10.965333 -13.645067
141
+ v -11.604176 10.965333 -11.604176
142
+ v -13.645067 10.965333 -9.117341
143
+ v -15.161587 10.965333 -6.280132
144
+ v -16.095455 10.965333 -3.201581
145
+ v -16.410782 10.965333 0.000005
146
+ v -16.095453 10.965333 3.201591
147
+ v -15.161583 10.965333 6.280142
148
+ v -13.645061 10.965333 9.117350
149
+ v -11.604168 10.965333 11.604183
150
+ v -9.117332 10.965333 13.645074
151
+ v -6.280122 10.965333 15.161591
152
+ v -3.201571 10.965333 16.095457
153
+ v 0.000016 10.965333 16.410782
154
+ v 3.201602 10.965333 16.095451
155
+ v 6.280151 10.965333 15.161579
156
+ v 9.117358 10.965333 13.645056
157
+ v 11.604191 10.965333 11.604160
158
+ v 13.645080 10.965333 9.117324
159
+ v 15.161595 10.965333 6.280113
160
+ v 16.095459 10.965333 3.201560
161
+ v 16.410782 10.965333 -0.000026
162
+ v 16.095448 10.965333 -3.201612
163
+ v 15.161575 10.965333 -6.280161
164
+ v 13.645050 10.965333 -9.117368
165
+ v 11.604154 10.965333 -11.604198
166
+ v 9.117315 10.965333 -13.645085
167
+ v 6.280103 10.965333 -15.161599
168
+ v 3.201550 10.965333 -16.095461
169
+ v -0.000001 7.553053 -18.234684
170
+ v -3.557410 7.553053 -17.884310
171
+ v -6.978111 7.553053 -16.846651
172
+ v -10.130647 7.553053 -15.161587
173
+ v -12.893868 7.553053 -12.893868
174
+ v -15.161587 7.553053 -10.130647
175
+ v -16.846653 7.553053 -6.978108
176
+ v -17.884310 7.553053 -3.557406
177
+ v -18.234684 7.553053 0.000006
178
+ v -17.884308 7.553053 3.557418
179
+ v -16.846647 7.553053 6.978120
180
+ v -15.161580 7.553053 10.130656
181
+ v -12.893860 7.553053 12.893877
182
+ v -10.130636 7.553053 15.161592
183
+ v -6.978098 7.553053 16.846657
184
+ v -3.557395 7.553053 17.884314
185
+ v 0.000018 7.553053 18.234684
186
+ v 3.557429 7.553053 17.884306
187
+ v 6.978130 7.553053 16.846643
188
+ v 10.130666 7.553053 15.161573
189
+ v 12.893886 7.553053 12.893852
190
+ v 15.161599 7.553053 10.130627
191
+ v 16.846661 7.553053 6.978087
192
+ v 17.884315 7.553053 3.557383
193
+ v 18.234684 7.553053 -0.000029
194
+ v 17.884304 7.553053 -3.557441
195
+ v 16.846640 7.553053 -6.978141
196
+ v 15.161567 7.553053 -10.130675
197
+ v 12.893844 7.553053 -12.893893
198
+ v 10.130617 7.553053 -15.161606
199
+ v 6.978076 7.553053 -16.846666
200
+ v 3.557372 7.553053 -17.884317
201
+ v -0.000001 3.850514 -19.357838
202
+ v -3.776527 3.850514 -18.985882
203
+ v -7.407923 3.850514 -17.884310
204
+ v -10.754637 3.850514 -16.095453
205
+ v -13.688058 3.850514 -13.688058
206
+ v -16.095453 3.850514 -10.754637
207
+ v -17.884310 3.850514 -7.407920
208
+ v -18.985882 3.850514 -3.776522
209
+ v -19.357838 3.850514 0.000006
210
+ v -18.985880 3.850514 3.776534
211
+ v -17.884306 3.850514 7.407932
212
+ v -16.095448 3.850514 10.754647
213
+ v -13.688049 3.850514 13.688066
214
+ v -10.754626 3.850514 16.095461
215
+ v -7.407909 3.850514 17.884315
216
+ v -3.776510 3.850514 18.985886
217
+ v 0.000019 3.850514 19.357838
218
+ v 3.776546 3.850514 18.985878
219
+ v 7.407944 3.850514 17.884300
220
+ v 10.754658 3.850514 16.095440
221
+ v 13.688075 3.850514 13.688040
222
+ v 16.095469 3.850514 10.754616
223
+ v 17.884319 3.850514 7.407897
224
+ v 18.985888 3.850514 3.776498
225
+ v 19.357838 3.850514 -0.000031
226
+ v 18.985876 3.850514 -3.776559
227
+ v 17.884296 3.850514 -7.407955
228
+ v 16.095434 3.850514 -10.754667
229
+ v 13.688031 3.850514 -13.688085
230
+ v 10.754605 3.850514 -16.095474
231
+ v 7.407886 3.850514 -17.884325
232
+ v 3.776485 3.850514 -18.985889
233
+ v -0.000001 0.000001 -19.737080
234
+ v -3.850513 0.000001 -19.357838
235
+ v -7.553053 0.000001 -18.234684
236
+ v -10.965333 0.000001 -16.410782
237
+ v -13.956223 0.000001 -13.956223
238
+ v -16.410784 0.000001 -10.965333
239
+ v -18.234686 0.000001 -7.553051
240
+ v -19.357838 0.000001 -3.850508
241
+ v -19.737080 0.000001 0.000006
242
+ v -19.357836 0.000001 3.850521
243
+ v -18.234680 0.000001 7.553062
244
+ v -16.410776 0.000001 10.965343
245
+ v -13.956214 0.000001 13.956232
246
+ v -10.965322 0.000001 16.410789
247
+ v -7.553039 0.000001 18.234690
248
+ v -3.850496 0.000001 19.357841
249
+ v 0.000019 0.000001 19.737080
250
+ v 3.850533 0.000001 19.357834
251
+ v 7.553074 0.000001 18.234674
252
+ v 10.965354 0.000001 16.410769
253
+ v 13.956241 0.000001 13.956205
254
+ v 16.410797 0.000001 10.965311
255
+ v 18.234695 0.000001 7.553027
256
+ v 19.357843 0.000001 3.850484
257
+ v 19.737080 0.000001 -0.000032
258
+ v 19.357830 0.000001 -3.850546
259
+ v 18.234671 0.000001 -7.553085
260
+ v 16.410761 0.000001 -10.965364
261
+ v 13.956196 0.000001 -13.956249
262
+ v 10.965301 0.000001 -16.410805
263
+ v 7.553015 0.000001 -18.234699
264
+ v 3.850471 0.000001 -19.357845
265
+ v -0.000001 -3.850511 -19.357838
266
+ v -3.776527 -3.850511 -18.985882
267
+ v -7.407923 -3.850511 -17.884310
268
+ v -10.754637 -3.850511 -16.095455
269
+ v -13.688058 -3.850511 -13.688058
270
+ v -16.095455 -3.850511 -10.754637
271
+ v -17.884312 -3.850511 -7.407921
272
+ v -18.985884 -3.850511 -3.776522
273
+ v -19.357838 -3.850511 0.000006
274
+ v -18.985880 -3.850511 3.776535
275
+ v -17.884306 -3.850511 7.407932
276
+ v -16.095448 -3.850511 10.754647
277
+ v -13.688049 -3.850511 13.688067
278
+ v -10.754626 -3.850511 16.095461
279
+ v -7.407909 -3.850511 17.884315
280
+ v -3.776510 -3.850511 18.985886
281
+ v 0.000019 -3.850511 19.357838
282
+ v 3.776547 -3.850511 18.985878
283
+ v 7.407944 -3.850511 17.884302
284
+ v 10.754658 -3.850511 16.095440
285
+ v 13.688076 -3.850511 13.688041
286
+ v 16.095469 -3.850511 10.754617
287
+ v 17.884321 -3.850511 7.407898
288
+ v 18.985888 -3.850511 3.776498
289
+ v 19.357838 -3.850511 -0.000031
290
+ v 18.985876 -3.850511 -3.776559
291
+ v 17.884296 -3.850511 -7.407955
292
+ v 16.095434 -3.850511 -10.754668
293
+ v 13.688032 -3.850511 -13.688085
294
+ v 10.754606 -3.850511 -16.095476
295
+ v 7.407887 -3.850511 -17.884325
296
+ v 3.776486 -3.850511 -18.985889
297
+ v -0.000001 -7.553051 -18.234686
298
+ v -3.557411 -7.553051 -17.884310
299
+ v -6.978111 -7.553051 -16.846653
300
+ v -10.130647 -7.553051 -15.161588
301
+ v -12.893869 -7.553051 -12.893869
302
+ v -15.161588 -7.553051 -10.130647
303
+ v -16.846653 -7.553051 -6.978109
304
+ v -17.884312 -7.553051 -3.557406
305
+ v -18.234686 -7.553051 0.000006
306
+ v -17.884310 -7.553051 3.557418
307
+ v -16.846649 -7.553051 6.978120
308
+ v -15.161581 -7.553051 10.130657
309
+ v -12.893861 -7.553051 12.893878
310
+ v -10.130637 -7.553051 15.161593
311
+ v -6.978098 -7.553051 16.846659
312
+ v -3.557395 -7.553051 17.884314
313
+ v 0.000018 -7.553051 18.234686
314
+ v 3.557429 -7.553051 17.884308
315
+ v 6.978131 -7.553051 16.846645
316
+ v 10.130667 -7.553051 15.161574
317
+ v 12.893886 -7.553051 12.893853
318
+ v 15.161600 -7.553051 10.130628
319
+ v 16.846663 -7.553051 6.978087
320
+ v 17.884315 -7.553051 3.557383
321
+ v 18.234686 -7.553051 -0.000029
322
+ v 17.884304 -7.553051 -3.557441
323
+ v 16.846640 -7.553051 -6.978142
324
+ v 15.161568 -7.553051 -10.130676
325
+ v 12.893845 -7.553051 -12.893894
326
+ v 10.130618 -7.553051 -15.161607
327
+ v 6.978077 -7.553051 -16.846666
328
+ v 3.557372 -7.553051 -17.884319
329
+ v -0.000001 -10.965333 -16.410782
330
+ v -3.201585 -10.965333 -16.095453
331
+ v -6.280134 -10.965333 -15.161587
332
+ v -9.117341 -10.965333 -13.645068
333
+ v -11.604176 -10.965333 -11.604176
334
+ v -13.645068 -10.965333 -9.117341
335
+ v -15.161588 -10.965333 -6.280132
336
+ v -16.095455 -10.965333 -3.201581
337
+ v -16.410782 -10.965333 0.000005
338
+ v -16.095453 -10.965333 3.201591
339
+ v -15.161583 -10.965333 6.280142
340
+ v -13.645062 -10.965333 9.117351
341
+ v -11.604168 -10.965333 11.604183
342
+ v -9.117332 -10.965333 13.645074
343
+ v -6.280122 -10.965333 15.161592
344
+ v -3.201571 -10.965333 16.095457
345
+ v 0.000016 -10.965333 16.410782
346
+ v 3.201602 -10.965333 16.095451
347
+ v 6.280152 -10.965333 15.161579
348
+ v 9.117359 -10.965333 13.645056
349
+ v 11.604191 -10.965333 11.604161
350
+ v 13.645080 -10.965333 9.117324
351
+ v 15.161595 -10.965333 6.280113
352
+ v 16.095459 -10.965333 3.201560
353
+ v 16.410782 -10.965333 -0.000026
354
+ v 16.095449 -10.965333 -3.201612
355
+ v 15.161575 -10.965333 -6.280161
356
+ v 13.645050 -10.965333 -9.117368
357
+ v 11.604154 -10.965333 -11.604198
358
+ v 9.117315 -10.965333 -13.645085
359
+ v 6.280103 -10.965333 -15.161599
360
+ v 3.201550 -10.965333 -16.095461
361
+ v -0.000001 -13.956223 -13.956223
362
+ v -2.722724 -13.956223 -13.688058
363
+ v -5.340815 -13.956223 -12.893868
364
+ v -7.753661 -13.956223 -11.604176
365
+ v -9.868540 -13.956223 -9.868540
366
+ v -11.604176 -13.956223 -7.753661
367
+ v -12.893869 -13.956223 -5.340813
368
+ v -13.688059 -13.956223 -2.722721
369
+ v -13.956223 -13.956223 0.000005
370
+ v -13.688057 -13.956223 2.722729
371
+ v -12.893866 -13.956223 5.340821
372
+ v -11.604171 -13.956223 7.753668
373
+ v -9.868533 -13.956223 9.868546
374
+ v -7.753654 -13.956223 11.604180
375
+ v -5.340805 -13.956223 12.893873
376
+ v -2.722712 -13.956223 13.688060
377
+ v 0.000013 -13.956223 13.956223
378
+ v 2.722738 -13.956223 13.688055
379
+ v 5.340830 -13.956223 12.893863
380
+ v 7.753676 -13.956223 11.604166
381
+ v 9.868552 -13.956223 9.868527
382
+ v 11.604186 -13.956223 7.753646
383
+ v 12.893876 -13.956223 5.340796
384
+ v 13.688062 -13.956223 2.722703
385
+ v 13.956223 -13.956223 -0.000022
386
+ v 13.688053 -13.956223 -2.722747
387
+ v 12.893859 -13.956223 -5.340838
388
+ v 11.604161 -13.956223 -7.753684
389
+ v 9.868521 -13.956223 -9.868559
390
+ v 7.753639 -13.956223 -11.604191
391
+ v 5.340788 -13.956223 -12.893880
392
+ v 2.722694 -13.956223 -13.688064
393
+ v -0.000000 -16.410784 -10.965333
394
+ v -2.139230 -16.410784 -10.754637
395
+ v -4.196251 -16.410784 -10.130647
396
+ v -6.092011 -16.410784 -9.117341
397
+ v -7.753661 -16.410784 -7.753661
398
+ v -9.117341 -16.410784 -6.092011
399
+ v -10.130647 -16.410784 -4.196249
400
+ v -10.754638 -16.410784 -2.139228
401
+ v -10.965333 -16.410784 0.000004
402
+ v -10.754636 -16.410784 2.139235
403
+ v -10.130644 -16.410784 4.196256
404
+ v -9.117337 -16.410784 6.092018
405
+ v -7.753656 -16.410784 7.753666
406
+ v -6.092006 -16.410784 9.117345
407
+ v -4.196243 -16.410784 10.130650
408
+ v -2.139221 -16.410784 10.754639
409
+ v 0.000011 -16.410784 10.965333
410
+ v 2.139241 -16.410784 10.754635
411
+ v 4.196262 -16.410784 10.130642
412
+ v 6.092023 -16.410784 9.117333
413
+ v 7.753671 -16.410784 7.753651
414
+ v 9.117349 -16.410784 6.092000
415
+ v 10.130652 -16.410784 4.196237
416
+ v 10.754640 -16.410784 2.139214
417
+ v 10.965333 -16.410784 -0.000018
418
+ v 10.754633 -16.410784 -2.139248
419
+ v 10.130639 -16.410784 -4.196269
420
+ v 9.117330 -16.410784 -6.092029
421
+ v 7.753646 -16.410784 -7.753676
422
+ v 6.091994 -16.410784 -9.117353
423
+ v 4.196230 -16.410784 -10.130655
424
+ v 2.139207 -16.410784 -10.754642
425
+ v -0.000000 -18.234686 -7.553051
426
+ v -1.473527 -18.234686 -7.407920
427
+ v -2.890427 -18.234686 -6.978109
428
+ v -4.196249 -18.234686 -6.280132
429
+ v -5.340813 -18.234686 -5.340813
430
+ v -6.280132 -18.234686 -4.196249
431
+ v -6.978109 -18.234686 -2.890426
432
+ v -7.407921 -18.234686 -1.473525
433
+ v -7.553051 -18.234686 0.000002
434
+ v -7.407920 -18.234686 1.473530
435
+ v -6.978107 -18.234686 2.890431
436
+ v -6.280129 -18.234686 4.196253
437
+ v -5.340810 -18.234686 5.340816
438
+ v -4.196245 -18.234686 6.280135
439
+ v -2.890422 -18.234686 6.978111
440
+ v -1.473521 -18.234686 7.407922
441
+ v 0.000007 -18.234686 7.553051
442
+ v 1.473535 -18.234686 7.407919
443
+ v 2.890435 -18.234686 6.978106
444
+ v 4.196258 -18.234686 6.280127
445
+ v 5.340820 -18.234686 5.340806
446
+ v 6.280138 -18.234686 4.196241
447
+ v 6.978113 -18.234686 2.890417
448
+ v 7.407923 -18.234686 1.473516
449
+ v 7.553051 -18.234686 -0.000012
450
+ v 7.407918 -18.234686 -1.473539
451
+ v 6.978104 -18.234686 -2.890440
452
+ v 6.280124 -18.234686 -4.196261
453
+ v 5.340803 -18.234686 -5.340823
454
+ v 4.196238 -18.234686 -6.280140
455
+ v 2.890413 -18.234686 -6.978115
456
+ v 1.473511 -18.234686 -7.407924
457
+ v -0.000000 -19.357838 -3.850508
458
+ v -0.751197 -19.357838 -3.776522
459
+ v -1.473526 -19.357838 -3.557406
460
+ v -2.139228 -19.357838 -3.201581
461
+ v -2.722721 -19.357838 -2.722721
462
+ v -3.201581 -19.357838 -2.139228
463
+ v -3.557406 -19.357838 -1.473525
464
+ v -3.776522 -19.357838 -0.751196
465
+ v -3.850508 -19.357838 0.000001
466
+ v -3.776522 -19.357838 0.751198
467
+ v -3.557405 -19.357838 1.473528
468
+ v -3.201580 -19.357838 2.139230
469
+ v -2.722719 -19.357838 2.722722
470
+ v -2.139225 -19.357838 3.201582
471
+ v -1.473523 -19.357838 3.557407
472
+ v -0.751194 -19.357838 3.776523
473
+ v 0.000004 -19.357838 3.850508
474
+ v 0.751201 -19.357838 3.776521
475
+ v 1.473530 -19.357838 3.557404
476
+ v 2.139232 -19.357838 3.201578
477
+ v 2.722724 -19.357838 2.722717
478
+ v 3.201584 -19.357838 2.139224
479
+ v 3.557408 -19.357838 1.473521
480
+ v 3.776523 -19.357838 0.751191
481
+ v 3.850508 -19.357838 -0.000006
482
+ v 3.776521 -19.357838 -0.751203
483
+ v 3.557403 -19.357838 -1.473532
484
+ v 3.201577 -19.357838 -2.139234
485
+ v 2.722715 -19.357838 -2.722726
486
+ v 2.139221 -19.357838 -3.201585
487
+ v 1.473518 -19.357838 -3.557409
488
+ v 0.751189 -19.357838 -3.776524
489
+ v 0.000000 -19.737080 -0.000000
490
+ # 482 vertices
491
+
492
+ vt 0.000000 1.000000 0.000000
493
+ vt 0.031250 1.000000 0.000000
494
+ vt 0.062500 1.000000 0.000000
495
+ vt 0.093750 1.000000 0.000000
496
+ vt 0.125000 1.000000 0.000000
497
+ vt 0.156250 1.000000 0.000000
498
+ vt 0.187500 1.000000 0.000000
499
+ vt 0.218750 1.000000 0.000000
500
+ vt 0.250000 1.000000 0.000000
501
+ vt 0.281250 1.000000 0.000000
502
+ vt 0.312500 1.000000 0.000000
503
+ vt 0.343750 1.000000 0.000000
504
+ vt 0.375000 1.000000 0.000000
505
+ vt 0.406250 1.000000 0.000000
506
+ vt 0.437500 1.000000 0.000000
507
+ vt 0.468750 1.000000 0.000000
508
+ vt 0.500000 1.000000 0.000000
509
+ vt 0.531250 1.000000 0.000000
510
+ vt 0.562500 1.000000 0.000000
511
+ vt 0.593750 1.000000 0.000000
512
+ vt 0.625000 1.000000 0.000000
513
+ vt 0.656250 1.000000 0.000000
514
+ vt 0.687500 1.000000 0.000000
515
+ vt 0.718750 1.000000 0.000000
516
+ vt 0.750000 1.000000 0.000000
517
+ vt 0.781250 1.000000 0.000000
518
+ vt 0.812500 1.000000 0.000000
519
+ vt 0.843750 1.000000 0.000000
520
+ vt 0.875000 1.000000 0.000000
521
+ vt 0.906250 1.000000 0.000000
522
+ vt 0.937500 1.000000 0.000000
523
+ vt 0.968750 1.000000 0.000000
524
+ vt 1.000000 1.000000 0.000000
525
+ vt 0.000000 0.937500 0.000000
526
+ vt 0.031250 0.937500 0.000000
527
+ vt 0.062500 0.937500 0.000000
528
+ vt 0.093750 0.937500 0.000000
529
+ vt 0.125000 0.937500 0.000000
530
+ vt 0.156250 0.937500 0.000000
531
+ vt 0.187500 0.937500 0.000000
532
+ vt 0.218750 0.937500 0.000000
533
+ vt 0.250000 0.937500 0.000000
534
+ vt 0.281250 0.937500 0.000000
535
+ vt 0.312500 0.937500 0.000000
536
+ vt 0.343750 0.937500 0.000000
537
+ vt 0.375000 0.937500 0.000000
538
+ vt 0.406250 0.937500 0.000000
539
+ vt 0.437500 0.937500 0.000000
540
+ vt 0.468750 0.937500 0.000000
541
+ vt 0.500000 0.937500 0.000000
542
+ vt 0.531250 0.937500 0.000000
543
+ vt 0.562500 0.937500 0.000000
544
+ vt 0.593750 0.937500 0.000000
545
+ vt 0.625000 0.937500 0.000000
546
+ vt 0.656250 0.937500 0.000000
547
+ vt 0.687500 0.937500 0.000000
548
+ vt 0.718750 0.937500 0.000000
549
+ vt 0.750000 0.937500 0.000000
550
+ vt 0.781250 0.937500 0.000000
551
+ vt 0.812500 0.937500 0.000000
552
+ vt 0.843750 0.937500 0.000000
553
+ vt 0.875000 0.937500 0.000000
554
+ vt 0.906250 0.937500 0.000000
555
+ vt 0.937500 0.937500 0.000000
556
+ vt 0.968750 0.937500 0.000000
557
+ vt 1.000000 0.937500 0.000000
558
+ vt 0.000000 0.875000 0.000000
559
+ vt 0.031250 0.875000 0.000000
560
+ vt 0.062500 0.875000 0.000000
561
+ vt 0.093750 0.875000 0.000000
562
+ vt 0.125000 0.875000 0.000000
563
+ vt 0.156250 0.875000 0.000000
564
+ vt 0.187500 0.875000 0.000000
565
+ vt 0.218750 0.875000 0.000000
566
+ vt 0.250000 0.875000 0.000000
567
+ vt 0.281250 0.875000 0.000000
568
+ vt 0.312500 0.875000 0.000000
569
+ vt 0.343750 0.875000 0.000000
570
+ vt 0.375000 0.875000 0.000000
571
+ vt 0.406250 0.875000 0.000000
572
+ vt 0.437500 0.875000 0.000000
573
+ vt 0.468750 0.875000 0.000000
574
+ vt 0.500000 0.875000 0.000000
575
+ vt 0.531250 0.875000 0.000000
576
+ vt 0.562500 0.875000 0.000000
577
+ vt 0.593750 0.875000 0.000000
578
+ vt 0.625000 0.875000 0.000000
579
+ vt 0.656250 0.875000 0.000000
580
+ vt 0.687500 0.875000 0.000000
581
+ vt 0.718750 0.875000 0.000000
582
+ vt 0.750000 0.875000 0.000000
583
+ vt 0.781250 0.875000 0.000000
584
+ vt 0.812500 0.875000 0.000000
585
+ vt 0.843750 0.875000 0.000000
586
+ vt 0.875000 0.875000 0.000000
587
+ vt 0.906250 0.875000 0.000000
588
+ vt 0.937500 0.875000 0.000000
589
+ vt 0.968750 0.875000 0.000000
590
+ vt 1.000000 0.875000 0.000000
591
+ vt 0.000000 0.812500 0.000000
592
+ vt 0.031250 0.812500 0.000000
593
+ vt 0.062500 0.812500 0.000000
594
+ vt 0.093750 0.812500 0.000000
595
+ vt 0.125000 0.812500 0.000000
596
+ vt 0.156250 0.812500 0.000000
597
+ vt 0.187500 0.812500 0.000000
598
+ vt 0.218750 0.812500 0.000000
599
+ vt 0.250000 0.812500 0.000000
600
+ vt 0.281250 0.812500 0.000000
601
+ vt 0.312500 0.812500 0.000000
602
+ vt 0.343750 0.812500 0.000000
603
+ vt 0.375000 0.812500 0.000000
604
+ vt 0.406250 0.812500 0.000000
605
+ vt 0.437500 0.812500 0.000000
606
+ vt 0.468750 0.812500 0.000000
607
+ vt 0.500000 0.812500 0.000000
608
+ vt 0.531250 0.812500 0.000000
609
+ vt 0.562500 0.812500 0.000000
610
+ vt 0.593750 0.812500 0.000000
611
+ vt 0.625000 0.812500 0.000000
612
+ vt 0.656250 0.812500 0.000000
613
+ vt 0.687500 0.812500 0.000000
614
+ vt 0.718750 0.812500 0.000000
615
+ vt 0.750000 0.812500 0.000000
616
+ vt 0.781250 0.812500 0.000000
617
+ vt 0.812500 0.812500 0.000000
618
+ vt 0.843750 0.812500 0.000000
619
+ vt 0.875000 0.812500 0.000000
620
+ vt 0.906250 0.812500 0.000000
621
+ vt 0.937500 0.812500 0.000000
622
+ vt 0.968750 0.812500 0.000000
623
+ vt 1.000000 0.812500 0.000000
624
+ vt 0.000000 0.750000 0.000000
625
+ vt 0.031250 0.750000 0.000000
626
+ vt 0.062500 0.750000 0.000000
627
+ vt 0.093750 0.750000 0.000000
628
+ vt 0.125000 0.750000 0.000000
629
+ vt 0.156250 0.750000 0.000000
630
+ vt 0.187500 0.750000 0.000000
631
+ vt 0.218750 0.750000 0.000000
632
+ vt 0.250000 0.750000 0.000000
633
+ vt 0.281250 0.750000 0.000000
634
+ vt 0.312500 0.750000 0.000000
635
+ vt 0.343750 0.750000 0.000000
636
+ vt 0.375000 0.750000 0.000000
637
+ vt 0.406250 0.750000 0.000000
638
+ vt 0.437500 0.750000 0.000000
639
+ vt 0.468750 0.750000 0.000000
640
+ vt 0.500000 0.750000 0.000000
641
+ vt 0.531250 0.750000 0.000000
642
+ vt 0.562500 0.750000 0.000000
643
+ vt 0.593750 0.750000 0.000000
644
+ vt 0.625000 0.750000 0.000000
645
+ vt 0.656250 0.750000 0.000000
646
+ vt 0.687500 0.750000 0.000000
647
+ vt 0.718750 0.750000 0.000000
648
+ vt 0.750000 0.750000 0.000000
649
+ vt 0.781250 0.750000 0.000000
650
+ vt 0.812500 0.750000 0.000000
651
+ vt 0.843750 0.750000 0.000000
652
+ vt 0.875000 0.750000 0.000000
653
+ vt 0.906250 0.750000 0.000000
654
+ vt 0.937500 0.750000 0.000000
655
+ vt 0.968750 0.750000 0.000000
656
+ vt 1.000000 0.750000 0.000000
657
+ vt 0.000000 0.687500 0.000000
658
+ vt 0.031250 0.687500 0.000000
659
+ vt 0.062500 0.687500 0.000000
660
+ vt 0.093750 0.687500 0.000000
661
+ vt 0.125000 0.687500 0.000000
662
+ vt 0.156250 0.687500 0.000000
663
+ vt 0.187500 0.687500 0.000000
664
+ vt 0.218750 0.687500 0.000000
665
+ vt 0.250000 0.687500 0.000000
666
+ vt 0.281250 0.687500 0.000000
667
+ vt 0.312500 0.687500 0.000000
668
+ vt 0.343750 0.687500 0.000000
669
+ vt 0.375000 0.687500 0.000000
670
+ vt 0.406250 0.687500 0.000000
671
+ vt 0.437500 0.687500 0.000000
672
+ vt 0.468750 0.687500 0.000000
673
+ vt 0.500000 0.687500 0.000000
674
+ vt 0.531250 0.687500 0.000000
675
+ vt 0.562500 0.687500 0.000000
676
+ vt 0.593750 0.687500 0.000000
677
+ vt 0.625000 0.687500 0.000000
678
+ vt 0.656250 0.687500 0.000000
679
+ vt 0.687500 0.687500 0.000000
680
+ vt 0.718750 0.687500 0.000000
681
+ vt 0.750000 0.687500 0.000000
682
+ vt 0.781250 0.687500 0.000000
683
+ vt 0.812500 0.687500 0.000000
684
+ vt 0.843750 0.687500 0.000000
685
+ vt 0.875000 0.687500 0.000000
686
+ vt 0.906250 0.687500 0.000000
687
+ vt 0.937500 0.687500 0.000000
688
+ vt 0.968750 0.687500 0.000000
689
+ vt 1.000000 0.687500 0.000000
690
+ vt 0.000000 0.625000 0.000000
691
+ vt 0.031250 0.625000 0.000000
692
+ vt 0.062500 0.625000 0.000000
693
+ vt 0.093750 0.625000 0.000000
694
+ vt 0.125000 0.625000 0.000000
695
+ vt 0.156250 0.625000 0.000000
696
+ vt 0.187500 0.625000 0.000000
697
+ vt 0.218750 0.625000 0.000000
698
+ vt 0.250000 0.625000 0.000000
699
+ vt 0.281250 0.625000 0.000000
700
+ vt 0.312500 0.625000 0.000000
701
+ vt 0.343750 0.625000 0.000000
702
+ vt 0.375000 0.625000 0.000000
703
+ vt 0.406250 0.625000 0.000000
704
+ vt 0.437500 0.625000 0.000000
705
+ vt 0.468750 0.625000 0.000000
706
+ vt 0.500000 0.625000 0.000000
707
+ vt 0.531250 0.625000 0.000000
708
+ vt 0.562500 0.625000 0.000000
709
+ vt 0.593750 0.625000 0.000000
710
+ vt 0.625000 0.625000 0.000000
711
+ vt 0.656250 0.625000 0.000000
712
+ vt 0.687500 0.625000 0.000000
713
+ vt 0.718750 0.625000 0.000000
714
+ vt 0.750000 0.625000 0.000000
715
+ vt 0.781250 0.625000 0.000000
716
+ vt 0.812500 0.625000 0.000000
717
+ vt 0.843750 0.625000 0.000000
718
+ vt 0.875000 0.625000 0.000000
719
+ vt 0.906250 0.625000 0.000000
720
+ vt 0.937500 0.625000 0.000000
721
+ vt 0.968750 0.625000 0.000000
722
+ vt 1.000000 0.625000 0.000000
723
+ vt 0.000000 0.562500 0.000000
724
+ vt 0.031250 0.562500 0.000000
725
+ vt 0.062500 0.562500 0.000000
726
+ vt 0.093750 0.562500 0.000000
727
+ vt 0.125000 0.562500 0.000000
728
+ vt 0.156250 0.562500 0.000000
729
+ vt 0.187500 0.562500 0.000000
730
+ vt 0.218750 0.562500 0.000000
731
+ vt 0.250000 0.562500 0.000000
732
+ vt 0.281250 0.562500 0.000000
733
+ vt 0.312500 0.562500 0.000000
734
+ vt 0.343750 0.562500 0.000000
735
+ vt 0.375000 0.562500 0.000000
736
+ vt 0.406250 0.562500 0.000000
737
+ vt 0.437500 0.562500 0.000000
738
+ vt 0.468750 0.562500 0.000000
739
+ vt 0.500000 0.562500 0.000000
740
+ vt 0.531250 0.562500 0.000000
741
+ vt 0.562500 0.562500 0.000000
742
+ vt 0.593750 0.562500 0.000000
743
+ vt 0.625000 0.562500 0.000000
744
+ vt 0.656250 0.562500 0.000000
745
+ vt 0.687500 0.562500 0.000000
746
+ vt 0.718750 0.562500 0.000000
747
+ vt 0.750000 0.562500 0.000000
748
+ vt 0.781250 0.562500 0.000000
749
+ vt 0.812500 0.562500 0.000000
750
+ vt 0.843750 0.562500 0.000000
751
+ vt 0.875000 0.562500 0.000000
752
+ vt 0.906250 0.562500 0.000000
753
+ vt 0.937500 0.562500 0.000000
754
+ vt 0.968750 0.562500 0.000000
755
+ vt 1.000000 0.562500 0.000000
756
+ vt 0.000000 0.500000 0.000000
757
+ vt 0.031250 0.500000 0.000000
758
+ vt 0.062500 0.500000 0.000000
759
+ vt 0.093750 0.500000 0.000000
760
+ vt 0.125000 0.500000 0.000000
761
+ vt 0.156250 0.500000 0.000000
762
+ vt 0.187500 0.500000 0.000000
763
+ vt 0.218750 0.500000 0.000000
764
+ vt 0.250000 0.500000 0.000000
765
+ vt 0.281250 0.500000 0.000000
766
+ vt 0.312500 0.500000 0.000000
767
+ vt 0.343750 0.500000 0.000000
768
+ vt 0.375000 0.500000 0.000000
769
+ vt 0.406250 0.500000 0.000000
770
+ vt 0.437500 0.500000 0.000000
771
+ vt 0.468750 0.500000 0.000000
772
+ vt 0.500000 0.500000 0.000000
773
+ vt 0.531250 0.500000 0.000000
774
+ vt 0.562500 0.500000 0.000000
775
+ vt 0.593750 0.500000 0.000000
776
+ vt 0.625000 0.500000 0.000000
777
+ vt 0.656250 0.500000 0.000000
778
+ vt 0.687500 0.500000 0.000000
779
+ vt 0.718750 0.500000 0.000000
780
+ vt 0.750000 0.500000 0.000000
781
+ vt 0.781250 0.500000 0.000000
782
+ vt 0.812500 0.500000 0.000000
783
+ vt 0.843750 0.500000 0.000000
784
+ vt 0.875000 0.500000 0.000000
785
+ vt 0.906250 0.500000 0.000000
786
+ vt 0.937500 0.500000 0.000000
787
+ vt 0.968750 0.500000 0.000000
788
+ vt 1.000000 0.500000 0.000000
789
+ vt 0.000000 0.437500 0.000000
790
+ vt 0.031250 0.437500 0.000000
791
+ vt 0.062500 0.437500 0.000000
792
+ vt 0.093750 0.437500 0.000000
793
+ vt 0.125000 0.437500 0.000000
794
+ vt 0.156250 0.437500 0.000000
795
+ vt 0.187500 0.437500 0.000000
796
+ vt 0.218750 0.437500 0.000000
797
+ vt 0.250000 0.437500 0.000000
798
+ vt 0.281250 0.437500 0.000000
799
+ vt 0.312500 0.437500 0.000000
800
+ vt 0.343750 0.437500 0.000000
801
+ vt 0.375000 0.437500 0.000000
802
+ vt 0.406250 0.437500 0.000000
803
+ vt 0.437500 0.437500 0.000000
804
+ vt 0.468750 0.437500 0.000000
805
+ vt 0.500000 0.437500 0.000000
806
+ vt 0.531250 0.437500 0.000000
807
+ vt 0.562500 0.437500 0.000000
808
+ vt 0.593750 0.437500 0.000000
809
+ vt 0.625000 0.437500 0.000000
810
+ vt 0.656250 0.437500 0.000000
811
+ vt 0.687500 0.437500 0.000000
812
+ vt 0.718750 0.437500 0.000000
813
+ vt 0.750000 0.437500 0.000000
814
+ vt 0.781250 0.437500 0.000000
815
+ vt 0.812500 0.437500 0.000000
816
+ vt 0.843750 0.437500 0.000000
817
+ vt 0.875000 0.437500 0.000000
818
+ vt 0.906250 0.437500 0.000000
819
+ vt 0.937500 0.437500 0.000000
820
+ vt 0.968750 0.437500 0.000000
821
+ vt 1.000000 0.437500 0.000000
822
+ vt 0.000000 0.375000 0.000000
823
+ vt 0.031250 0.375000 0.000000
824
+ vt 0.062500 0.375000 0.000000
825
+ vt 0.093750 0.375000 0.000000
826
+ vt 0.125000 0.375000 0.000000
827
+ vt 0.156250 0.375000 0.000000
828
+ vt 0.187500 0.375000 0.000000
829
+ vt 0.218750 0.375000 0.000000
830
+ vt 0.250000 0.375000 0.000000
831
+ vt 0.281250 0.375000 0.000000
832
+ vt 0.312500 0.375000 0.000000
833
+ vt 0.343750 0.375000 0.000000
834
+ vt 0.375000 0.375000 0.000000
835
+ vt 0.406250 0.375000 0.000000
836
+ vt 0.437500 0.375000 0.000000
837
+ vt 0.468750 0.375000 0.000000
838
+ vt 0.500000 0.375000 0.000000
839
+ vt 0.531250 0.375000 0.000000
840
+ vt 0.562500 0.375000 0.000000
841
+ vt 0.593750 0.375000 0.000000
842
+ vt 0.625000 0.375000 0.000000
843
+ vt 0.656250 0.375000 0.000000
844
+ vt 0.687500 0.375000 0.000000
845
+ vt 0.718750 0.375000 0.000000
846
+ vt 0.750000 0.375000 0.000000
847
+ vt 0.781250 0.375000 0.000000
848
+ vt 0.812500 0.375000 0.000000
849
+ vt 0.843750 0.375000 0.000000
850
+ vt 0.875000 0.375000 0.000000
851
+ vt 0.906250 0.375000 0.000000
852
+ vt 0.937500 0.375000 0.000000
853
+ vt 0.968750 0.375000 0.000000
854
+ vt 1.000000 0.375000 0.000000
855
+ vt 0.000000 0.312500 0.000000
856
+ vt 0.031250 0.312500 0.000000
857
+ vt 0.062500 0.312500 0.000000
858
+ vt 0.093750 0.312500 0.000000
859
+ vt 0.125000 0.312500 0.000000
860
+ vt 0.156250 0.312500 0.000000
861
+ vt 0.187500 0.312500 0.000000
862
+ vt 0.218750 0.312500 0.000000
863
+ vt 0.250000 0.312500 0.000000
864
+ vt 0.281250 0.312500 0.000000
865
+ vt 0.312500 0.312500 0.000000
866
+ vt 0.343750 0.312500 0.000000
867
+ vt 0.375000 0.312500 0.000000
868
+ vt 0.406250 0.312500 0.000000
869
+ vt 0.437500 0.312500 0.000000
870
+ vt 0.468750 0.312500 0.000000
871
+ vt 0.500000 0.312500 0.000000
872
+ vt 0.531250 0.312500 0.000000
873
+ vt 0.562500 0.312500 0.000000
874
+ vt 0.593750 0.312500 0.000000
875
+ vt 0.625000 0.312500 0.000000
876
+ vt 0.656250 0.312500 0.000000
877
+ vt 0.687500 0.312500 0.000000
878
+ vt 0.718750 0.312500 0.000000
879
+ vt 0.750000 0.312500 0.000000
880
+ vt 0.781250 0.312500 0.000000
881
+ vt 0.812500 0.312500 0.000000
882
+ vt 0.843750 0.312500 0.000000
883
+ vt 0.875000 0.312500 0.000000
884
+ vt 0.906250 0.312500 0.000000
885
+ vt 0.937500 0.312500 0.000000
886
+ vt 0.968750 0.312500 0.000000
887
+ vt 1.000000 0.312500 0.000000
888
+ vt 0.000000 0.250000 0.000000
889
+ vt 0.031250 0.250000 0.000000
890
+ vt 0.062500 0.250000 0.000000
891
+ vt 0.093750 0.250000 0.000000
892
+ vt 0.125000 0.250000 0.000000
893
+ vt 0.156250 0.250000 0.000000
894
+ vt 0.187500 0.250000 0.000000
895
+ vt 0.218750 0.250000 0.000000
896
+ vt 0.250000 0.250000 0.000000
897
+ vt 0.281250 0.250000 0.000000
898
+ vt 0.312500 0.250000 0.000000
899
+ vt 0.343750 0.250000 0.000000
900
+ vt 0.375000 0.250000 0.000000
901
+ vt 0.406250 0.250000 0.000000
902
+ vt 0.437500 0.250000 0.000000
903
+ vt 0.468750 0.250000 0.000000
904
+ vt 0.500000 0.250000 0.000000
905
+ vt 0.531250 0.250000 0.000000
906
+ vt 0.562500 0.250000 0.000000
907
+ vt 0.593750 0.250000 0.000000
908
+ vt 0.625000 0.250000 0.000000
909
+ vt 0.656250 0.250000 0.000000
910
+ vt 0.687500 0.250000 0.000000
911
+ vt 0.718750 0.250000 0.000000
912
+ vt 0.750000 0.250000 0.000000
913
+ vt 0.781250 0.250000 0.000000
914
+ vt 0.812500 0.250000 0.000000
915
+ vt 0.843750 0.250000 0.000000
916
+ vt 0.875000 0.250000 0.000000
917
+ vt 0.906250 0.250000 0.000000
918
+ vt 0.937500 0.250000 0.000000
919
+ vt 0.968750 0.250000 0.000000
920
+ vt 1.000000 0.250000 0.000000
921
+ vt 0.000000 0.187500 0.000000
922
+ vt 0.031250 0.187500 0.000000
923
+ vt 0.062500 0.187500 0.000000
924
+ vt 0.093750 0.187500 0.000000
925
+ vt 0.125000 0.187500 0.000000
926
+ vt 0.156250 0.187500 0.000000
927
+ vt 0.187500 0.187500 0.000000
928
+ vt 0.218750 0.187500 0.000000
929
+ vt 0.250000 0.187500 0.000000
930
+ vt 0.281250 0.187500 0.000000
931
+ vt 0.312500 0.187500 0.000000
932
+ vt 0.343750 0.187500 0.000000
933
+ vt 0.375000 0.187500 0.000000
934
+ vt 0.406250 0.187500 0.000000
935
+ vt 0.437500 0.187500 0.000000
936
+ vt 0.468750 0.187500 0.000000
937
+ vt 0.500000 0.187500 0.000000
938
+ vt 0.531250 0.187500 0.000000
939
+ vt 0.562500 0.187500 0.000000
940
+ vt 0.593750 0.187500 0.000000
941
+ vt 0.625000 0.187500 0.000000
942
+ vt 0.656250 0.187500 0.000000
943
+ vt 0.687500 0.187500 0.000000
944
+ vt 0.718750 0.187500 0.000000
945
+ vt 0.750000 0.187500 0.000000
946
+ vt 0.781250 0.187500 0.000000
947
+ vt 0.812500 0.187500 0.000000
948
+ vt 0.843750 0.187500 0.000000
949
+ vt 0.875000 0.187500 0.000000
950
+ vt 0.906250 0.187500 0.000000
951
+ vt 0.937500 0.187500 0.000000
952
+ vt 0.968750 0.187500 0.000000
953
+ vt 1.000000 0.187500 0.000000
954
+ vt 0.000000 0.125000 0.000000
955
+ vt 0.031250 0.125000 0.000000
956
+ vt 0.062500 0.125000 0.000000
957
+ vt 0.093750 0.125000 0.000000
958
+ vt 0.125000 0.125000 0.000000
959
+ vt 0.156250 0.125000 0.000000
960
+ vt 0.187500 0.125000 0.000000
961
+ vt 0.218750 0.125000 0.000000
962
+ vt 0.250000 0.125000 0.000000
963
+ vt 0.281250 0.125000 0.000000
964
+ vt 0.312500 0.125000 0.000000
965
+ vt 0.343750 0.125000 0.000000
966
+ vt 0.375000 0.125000 0.000000
967
+ vt 0.406250 0.125000 0.000000
968
+ vt 0.437500 0.125000 0.000000
969
+ vt 0.468750 0.125000 0.000000
970
+ vt 0.500000 0.125000 0.000000
971
+ vt 0.531250 0.125000 0.000000
972
+ vt 0.562500 0.125000 0.000000
973
+ vt 0.593750 0.125000 0.000000
974
+ vt 0.625000 0.125000 0.000000
975
+ vt 0.656250 0.125000 0.000000
976
+ vt 0.687500 0.125000 0.000000
977
+ vt 0.718750 0.125000 0.000000
978
+ vt 0.750000 0.125000 0.000000
979
+ vt 0.781250 0.125000 0.000000
980
+ vt 0.812500 0.125000 0.000000
981
+ vt 0.843750 0.125000 0.000000
982
+ vt 0.875000 0.125000 0.000000
983
+ vt 0.906250 0.125000 0.000000
984
+ vt 0.937500 0.125000 0.000000
985
+ vt 0.968750 0.125000 0.000000
986
+ vt 1.000000 0.125000 0.000000
987
+ vt 0.000000 0.062500 0.000000
988
+ vt 0.031250 0.062500 0.000000
989
+ vt 0.062500 0.062500 0.000000
990
+ vt 0.093750 0.062500 0.000000
991
+ vt 0.125000 0.062500 0.000000
992
+ vt 0.156250 0.062500 0.000000
993
+ vt 0.187500 0.062500 0.000000
994
+ vt 0.218750 0.062500 0.000000
995
+ vt 0.250000 0.062500 0.000000
996
+ vt 0.281250 0.062500 0.000000
997
+ vt 0.312500 0.062500 0.000000
998
+ vt 0.343750 0.062500 0.000000
999
+ vt 0.375000 0.062500 0.000000
1000
+ vt 0.406250 0.062500 0.000000
1001
+ vt 0.437500 0.062500 0.000000
1002
+ vt 0.468750 0.062500 0.000000
1003
+ vt 0.500000 0.062500 0.000000
1004
+ vt 0.531250 0.062500 0.000000
1005
+ vt 0.562500 0.062500 0.000000
1006
+ vt 0.593750 0.062500 0.000000
1007
+ vt 0.625000 0.062500 0.000000
1008
+ vt 0.656250 0.062500 0.000000
1009
+ vt 0.687500 0.062500 0.000000
1010
+ vt 0.718750 0.062500 0.000000
1011
+ vt 0.750000 0.062500 0.000000
1012
+ vt 0.781250 0.062500 0.000000
1013
+ vt 0.812500 0.062500 0.000000
1014
+ vt 0.843750 0.062500 0.000000
1015
+ vt 0.875000 0.062500 0.000000
1016
+ vt 0.906250 0.062500 0.000000
1017
+ vt 0.937500 0.062500 0.000000
1018
+ vt 0.968750 0.062500 0.000000
1019
+ vt 1.000000 0.062500 0.000000
1020
+ vt 0.000000 -0.000000 0.000000
1021
+ vt 0.031250 -0.000000 0.000000
1022
+ vt 0.062500 -0.000000 0.000000
1023
+ vt 0.093750 -0.000000 0.000000
1024
+ vt 0.125000 -0.000000 0.000000
1025
+ vt 0.156250 -0.000000 0.000000
1026
+ vt 0.187500 -0.000000 0.000000
1027
+ vt 0.218750 -0.000000 0.000000
1028
+ vt 0.250000 -0.000000 0.000000
1029
+ vt 0.281250 -0.000000 0.000000
1030
+ vt 0.312500 -0.000000 0.000000
1031
+ vt 0.343750 -0.000000 0.000000
1032
+ vt 0.375000 -0.000000 0.000000
1033
+ vt 0.406250 -0.000000 0.000000
1034
+ vt 0.437500 -0.000000 0.000000
1035
+ vt 0.468750 -0.000000 0.000000
1036
+ vt 0.500000 -0.000000 0.000000
1037
+ vt 0.531250 -0.000000 0.000000
1038
+ vt 0.562500 -0.000000 0.000000
1039
+ vt 0.593750 -0.000000 0.000000
1040
+ vt 0.625000 -0.000000 0.000000
1041
+ vt 0.656250 -0.000000 0.000000
1042
+ vt 0.687500 -0.000000 0.000000
1043
+ vt 0.718750 -0.000000 0.000000
1044
+ vt 0.750000 -0.000000 0.000000
1045
+ vt 0.781250 -0.000000 0.000000
1046
+ vt 0.812500 -0.000000 0.000000
1047
+ vt 0.843750 -0.000000 0.000000
1048
+ vt 0.875000 -0.000000 0.000000
1049
+ vt 0.906250 -0.000000 0.000000
1050
+ vt 0.937500 -0.000000 0.000000
1051
+ vt 0.968750 -0.000000 0.000000
1052
+ vt 1.000000 -0.000000 0.000000
1053
+ # 561 texture vertices
1054
+
1055
+ vn 0.000000 1.000000 -0.000000
1056
+ vn -0.005744 0.976740 -0.214348
1057
+ vn -0.047451 0.976740 -0.209109
1058
+ vn -0.087334 0.976740 -0.195834
1059
+ vn -0.123861 0.976740 -0.175033
1060
+ vn -0.155629 0.976740 -0.147506
1061
+ vn -0.181415 0.976740 -0.114310
1062
+ vn -0.200230 0.976740 -0.076721
1063
+ vn -0.211350 0.976740 -0.036184
1064
+ vn -0.214348 0.976740 0.005744
1065
+ vn -0.209109 0.976740 0.047451
1066
+ vn -0.195834 0.976740 0.087334
1067
+ vn -0.175033 0.976740 0.123861
1068
+ vn -0.147506 0.976740 0.155629
1069
+ vn -0.114310 0.976740 0.181415
1070
+ vn -0.076721 0.976740 0.200230
1071
+ vn -0.036184 0.976740 0.211350
1072
+ vn 0.005744 0.976740 0.214348
1073
+ vn 0.047451 0.976740 0.209109
1074
+ vn 0.087334 0.976740 0.195834
1075
+ vn 0.123862 0.976740 0.175033
1076
+ vn 0.155629 0.976740 0.147505
1077
+ vn 0.181415 0.976740 0.114309
1078
+ vn 0.200230 0.976740 0.076721
1079
+ vn 0.211350 0.976740 0.036184
1080
+ vn 0.214348 0.976740 -0.005744
1081
+ vn 0.209109 0.976740 -0.047451
1082
+ vn 0.195834 0.976740 -0.087334
1083
+ vn 0.175033 0.976740 -0.123862
1084
+ vn 0.147505 0.976740 -0.155629
1085
+ vn 0.114309 0.976740 -0.181415
1086
+ vn 0.076721 0.976740 -0.200230
1087
+ vn 0.036184 0.976740 -0.211350
1088
+ vn -0.002983 0.923888 -0.382651
1089
+ vn -0.077577 0.923888 -0.374717
1090
+ vn -0.149190 0.923888 -0.352382
1091
+ vn -0.215070 0.923888 -0.316506
1092
+ vn -0.272685 0.923888 -0.268466
1093
+ vn -0.319820 0.923888 -0.210109
1094
+ vn -0.354665 0.923888 -0.143678
1095
+ vn -0.375881 0.923888 -0.071726
1096
+ vn -0.382651 0.923888 0.002983
1097
+ vn -0.374717 0.923888 0.077578
1098
+ vn -0.352382 0.923888 0.149191
1099
+ vn -0.316506 0.923888 0.215070
1100
+ vn -0.268466 0.923888 0.272685
1101
+ vn -0.210109 0.923888 0.319821
1102
+ vn -0.143678 0.923888 0.354666
1103
+ vn -0.071725 0.923888 0.375881
1104
+ vn 0.002984 0.923888 0.382651
1105
+ vn 0.077578 0.923888 0.374717
1106
+ vn 0.149191 0.923888 0.352382
1107
+ vn 0.215071 0.923888 0.316505
1108
+ vn 0.272685 0.923888 0.268466
1109
+ vn 0.319821 0.923888 0.210109
1110
+ vn 0.354666 0.923888 0.143678
1111
+ vn 0.375881 0.923888 0.071725
1112
+ vn 0.382651 0.923888 -0.002984
1113
+ vn 0.374717 0.923888 -0.077578
1114
+ vn 0.352382 0.923888 -0.149191
1115
+ vn 0.316505 0.923888 -0.215071
1116
+ vn 0.268465 0.923888 -0.272685
1117
+ vn 0.210109 0.923888 -0.319821
1118
+ vn 0.143678 0.923888 -0.354666
1119
+ vn 0.071725 0.923888 -0.375881
1120
+ vn -0.002681 0.831490 -0.555533
1121
+ vn -0.111008 0.831490 -0.544335
1122
+ vn -0.215070 0.831490 -0.512219
1123
+ vn -0.310866 0.831490 -0.460419
1124
+ vn -0.394716 0.831490 -0.390925
1125
+ vn -0.463398 0.831490 -0.306408
1126
+ vn -0.514271 0.831490 -0.210116
1127
+ vn -0.545381 0.831490 -0.105750
1128
+ vn -0.555533 0.831490 0.002681
1129
+ vn -0.544335 0.831490 0.111008
1130
+ vn -0.512219 0.831490 0.215070
1131
+ vn -0.460419 0.831490 0.310867
1132
+ vn -0.390925 0.831490 0.394717
1133
+ vn -0.306408 0.831490 0.463398
1134
+ vn -0.210116 0.831490 0.514271
1135
+ vn -0.105749 0.831490 0.545381
1136
+ vn 0.002681 0.831490 0.555533
1137
+ vn 0.111009 0.831490 0.544335
1138
+ vn 0.215070 0.831490 0.512219
1139
+ vn 0.310867 0.831490 0.460419
1140
+ vn 0.394717 0.831490 0.390925
1141
+ vn 0.463398 0.831490 0.306408
1142
+ vn 0.514271 0.831490 0.210116
1143
+ vn 0.545381 0.831490 0.105749
1144
+ vn 0.555533 0.831490 -0.002681
1145
+ vn 0.544335 0.831490 -0.111009
1146
+ vn 0.512219 0.831490 -0.215071
1147
+ vn 0.460419 0.831490 -0.310867
1148
+ vn 0.390925 0.831490 -0.394717
1149
+ vn 0.306408 0.831490 -0.463398
1150
+ vn 0.210115 0.831490 -0.514271
1151
+ vn 0.105749 0.831490 -0.545381
1152
+ vn -0.002276 0.707138 -0.707072
1153
+ vn -0.140175 0.707138 -0.693042
1154
+ vn -0.272687 0.707138 -0.652379
1155
+ vn -0.394720 0.707138 -0.586645
1156
+ vn -0.501585 0.707138 -0.498367
1157
+ vn -0.589173 0.707138 -0.390936
1158
+ vn -0.654120 0.707138 -0.268482
1159
+ vn -0.693930 0.707138 -0.135711
1160
+ vn -0.707072 0.707138 0.002276
1161
+ vn -0.693042 0.707138 0.140175
1162
+ vn -0.652379 0.707138 0.272687
1163
+ vn -0.586645 0.707138 0.394721
1164
+ vn -0.498366 0.707138 0.501585
1165
+ vn -0.390936 0.707138 0.589174
1166
+ vn -0.268482 0.707138 0.654121
1167
+ vn -0.135711 0.707138 0.693930
1168
+ vn 0.002276 0.707138 0.707072
1169
+ vn 0.140176 0.707138 0.693042
1170
+ vn 0.272688 0.707138 0.652378
1171
+ vn 0.394721 0.707138 0.586644
1172
+ vn 0.501585 0.707138 0.498366
1173
+ vn 0.589174 0.707138 0.390935
1174
+ vn 0.654121 0.707138 0.268482
1175
+ vn 0.693930 0.707138 0.135710
1176
+ vn 0.707072 0.707138 -0.002277
1177
+ vn 0.693042 0.707138 -0.140176
1178
+ vn 0.652378 0.707138 -0.272688
1179
+ vn 0.586644 0.707138 -0.394721
1180
+ vn 0.498366 0.707138 -0.501585
1181
+ vn 0.390935 0.707138 -0.589174
1182
+ vn 0.268481 0.707138 -0.654121
1183
+ vn 0.135710 0.707138 -0.693930
1184
+ vn -0.001785 0.555605 -0.831445
1185
+ vn -0.163957 0.555605 -0.815120
1186
+ vn -0.319829 0.555605 -0.767472
1187
+ vn -0.463410 0.555605 -0.690329
1188
+ vn -0.589182 0.555605 -0.586658
1189
+ vn -0.692312 0.555605 -0.460442
1190
+ vn -0.768838 0.555605 -0.316531
1191
+ vn -0.815817 0.555605 -0.160456
1192
+ vn -0.831445 0.555605 0.001785
1193
+ vn -0.815120 0.555605 0.163957
1194
+ vn -0.767471 0.555605 0.319829
1195
+ vn -0.690329 0.555605 0.463410
1196
+ vn -0.586658 0.555605 0.589182
1197
+ vn -0.460441 0.555605 0.692313
1198
+ vn -0.316531 0.555605 0.768838
1199
+ vn -0.160456 0.555605 0.815817
1200
+ vn 0.001785 0.555605 0.831445
1201
+ vn 0.163958 0.555605 0.815120
1202
+ vn 0.319830 0.555605 0.767471
1203
+ vn 0.463410 0.555605 0.690329
1204
+ vn 0.589183 0.555605 0.586657
1205
+ vn 0.692313 0.555605 0.460441
1206
+ vn 0.768838 0.555605 0.316530
1207
+ vn 0.815817 0.555605 0.160455
1208
+ vn 0.831445 0.555605 -0.001786
1209
+ vn 0.815120 0.555605 -0.163958
1210
+ vn 0.767471 0.555605 -0.319830
1211
+ vn 0.690329 0.555605 -0.463411
1212
+ vn 0.586657 0.555605 -0.589183
1213
+ vn 0.460441 0.555605 -0.692313
1214
+ vn 0.316530 0.555605 -0.768838
1215
+ vn 0.160455 0.555605 -0.815817
1216
+ vn -0.001228 0.382713 -0.923866
1217
+ vn -0.181441 0.382713 -0.905875
1218
+ vn -0.354682 0.382713 -0.853072
1219
+ vn -0.514293 0.382713 -0.767485
1220
+ vn -0.654140 0.382713 -0.652404
1221
+ vn -0.768849 0.382713 -0.512252
1222
+ vn -0.854011 0.382713 -0.352414
1223
+ vn -0.906354 0.382713 -0.179033
1224
+ vn -0.923866 0.382713 0.001228
1225
+ vn -0.905875 0.382713 0.181441
1226
+ vn -0.853071 0.382713 0.354683
1227
+ vn -0.767485 0.382713 0.514294
1228
+ vn -0.652404 0.382713 0.654140
1229
+ vn -0.512252 0.382713 0.768849
1230
+ vn -0.352414 0.382713 0.854011
1231
+ vn -0.179033 0.382713 0.906354
1232
+ vn 0.001228 0.382713 0.923866
1233
+ vn 0.181442 0.382713 0.905875
1234
+ vn 0.354683 0.382713 0.853071
1235
+ vn 0.514294 0.382713 0.767484
1236
+ vn 0.654141 0.382713 0.652403
1237
+ vn 0.768849 0.382713 0.512251
1238
+ vn 0.854011 0.382713 0.352413
1239
+ vn 0.906354 0.382713 0.179032
1240
+ vn 0.923866 0.382713 -0.001229
1241
+ vn 0.905875 0.382713 -0.181443
1242
+ vn 0.853071 0.382713 -0.354684
1243
+ vn 0.767484 0.382713 -0.514295
1244
+ vn 0.652403 0.382713 -0.654141
1245
+ vn 0.512251 0.382713 -0.768850
1246
+ vn 0.352413 0.382713 -0.854012
1247
+ vn 0.179032 0.382713 -0.906354
1248
+ vn -0.000626 0.195108 -0.980782
1249
+ vn -0.191954 0.195108 -0.961814
1250
+ vn -0.375906 0.195108 -0.905885
1251
+ vn -0.545413 0.195108 -0.815143
1252
+ vn -0.693959 0.195108 -0.693075
1253
+ vn -0.815837 0.195108 -0.544373
1254
+ vn -0.906363 0.195108 -0.374751
1255
+ vn -0.962058 0.195108 -0.190728
1256
+ vn -0.980782 0.195108 0.000625
1257
+ vn -0.961814 0.195108 0.191954
1258
+ vn -0.905885 0.195108 0.375907
1259
+ vn -0.815143 0.195108 0.545413
1260
+ vn -0.693075 0.195108 0.693960
1261
+ vn -0.544373 0.195108 0.815838
1262
+ vn -0.374751 0.195108 0.906364
1263
+ vn -0.190727 0.195108 0.962058
1264
+ vn 0.000626 0.195108 0.980782
1265
+ vn 0.191955 0.195108 0.961814
1266
+ vn 0.375907 0.195108 0.905884
1267
+ vn 0.545414 0.195108 0.815142
1268
+ vn 0.693960 0.195108 0.693075
1269
+ vn 0.815838 0.195108 0.544372
1270
+ vn 0.906364 0.195108 0.374750
1271
+ vn 0.962058 0.195108 0.190727
1272
+ vn 0.980782 0.195108 -0.000627
1273
+ vn 0.961814 0.195108 -0.191956
1274
+ vn 0.905884 0.195108 -0.375908
1275
+ vn 0.815142 0.195108 -0.545414
1276
+ vn 0.693074 0.195108 -0.693961
1277
+ vn 0.544372 0.195108 -0.815839
1278
+ vn 0.374750 0.195108 -0.906364
1279
+ vn 0.190726 0.195108 -0.962058
1280
+ vn -0.000000 -0.000000 -1.000000
1281
+ vn -0.195090 -0.000000 -0.980785
1282
+ vn -0.382683 0.000000 -0.923880
1283
+ vn -0.555570 0.000000 -0.831470
1284
+ vn -0.707107 0.000000 -0.707107
1285
+ vn -0.831470 0.000000 -0.555570
1286
+ vn -0.923880 0.000000 -0.382683
1287
+ vn -0.980785 0.000000 -0.195090
1288
+ vn -1.000000 0.000000 0.000000
1289
+ vn -0.980785 -0.000000 0.195091
1290
+ vn -0.923879 0.000000 0.382684
1291
+ vn -0.831469 0.000000 0.555571
1292
+ vn -0.707106 0.000000 0.707107
1293
+ vn -0.555570 0.000000 0.831470
1294
+ vn -0.382683 -0.000000 0.923880
1295
+ vn -0.195089 0.000000 0.980785
1296
+ vn 0.000001 -0.000000 1.000000
1297
+ vn 0.195091 0.000000 0.980785
1298
+ vn 0.382685 0.000000 0.923879
1299
+ vn 0.555571 0.000000 0.831469
1300
+ vn 0.707108 0.000000 0.707106
1301
+ vn 0.831470 0.000000 0.555569
1302
+ vn 0.923880 0.000000 0.382682
1303
+ vn 0.980786 0.000000 0.195089
1304
+ vn 1.000000 0.000000 -0.000002
1305
+ vn 0.980785 -0.000000 -0.195092
1306
+ vn 0.923879 0.000000 -0.382685
1307
+ vn 0.831469 0.000000 -0.555572
1308
+ vn 0.707106 0.000000 -0.707108
1309
+ vn 0.555569 0.000000 -0.831471
1310
+ vn 0.382681 0.000000 -0.923880
1311
+ vn 0.195089 0.000000 -0.980786
1312
+ vn 0.000624 -0.195108 -0.980782
1313
+ vn -0.190728 -0.195108 -0.962058
1314
+ vn -0.374751 -0.195108 -0.906363
1315
+ vn -0.544373 -0.195107 -0.815837
1316
+ vn -0.693075 -0.195107 -0.693959
1317
+ vn -0.815143 -0.195108 -0.545413
1318
+ vn -0.905885 -0.195108 -0.375906
1319
+ vn -0.961814 -0.195107 -0.191954
1320
+ vn -0.980782 -0.195107 -0.000625
1321
+ vn -0.962058 -0.195107 0.190728
1322
+ vn -0.906363 -0.195107 0.374752
1323
+ vn -0.815837 -0.195108 0.544374
1324
+ vn -0.693959 -0.195108 0.693076
1325
+ vn -0.545412 -0.195107 0.815143
1326
+ vn -0.375906 -0.195107 0.905885
1327
+ vn -0.191953 -0.195108 0.961814
1328
+ vn -0.000624 -0.195107 0.980782
1329
+ vn 0.190729 -0.195107 0.962058
1330
+ vn 0.374753 -0.195107 0.906363
1331
+ vn 0.544374 -0.195107 0.815837
1332
+ vn 0.693076 -0.195108 0.693959
1333
+ vn 0.815144 -0.195108 0.545412
1334
+ vn 0.905885 -0.195108 0.375905
1335
+ vn 0.961815 -0.195108 0.191953
1336
+ vn 0.980782 -0.195108 0.000623
1337
+ vn 0.962058 -0.195107 -0.190730
1338
+ vn 0.906363 -0.195108 -0.374753
1339
+ vn 0.815836 -0.195107 -0.544375
1340
+ vn 0.693958 -0.195107 -0.693077
1341
+ vn 0.545411 -0.195108 -0.815144
1342
+ vn 0.375904 -0.195107 -0.905886
1343
+ vn 0.191953 -0.195107 -0.961815
1344
+ vn 0.001227 -0.382713 -0.923866
1345
+ vn -0.179034 -0.382713 -0.906354
1346
+ vn -0.352414 -0.382713 -0.854011
1347
+ vn -0.512252 -0.382713 -0.768849
1348
+ vn -0.652404 -0.382713 -0.654140
1349
+ vn -0.767485 -0.382713 -0.514293
1350
+ vn -0.853072 -0.382713 -0.354682
1351
+ vn -0.905875 -0.382713 -0.181441
1352
+ vn -0.923866 -0.382713 -0.001227
1353
+ vn -0.906354 -0.382713 0.179034
1354
+ vn -0.854011 -0.382713 0.352415
1355
+ vn -0.768848 -0.382713 0.512253
1356
+ vn -0.654140 -0.382713 0.652405
1357
+ vn -0.514293 -0.382713 0.767485
1358
+ vn -0.354682 -0.382713 0.853072
1359
+ vn -0.181440 -0.382713 0.905875
1360
+ vn -0.001227 -0.382713 0.923866
1361
+ vn 0.179035 -0.382713 0.906354
1362
+ vn 0.352415 -0.382713 0.854011
1363
+ vn 0.512253 -0.382713 0.768848
1364
+ vn 0.652405 -0.382713 0.654139
1365
+ vn 0.767486 -0.382713 0.514292
1366
+ vn 0.853072 -0.382713 0.354681
1367
+ vn 0.905875 -0.382713 0.181440
1368
+ vn 0.923866 -0.382713 0.001226
1369
+ vn 0.906354 -0.382713 -0.179035
1370
+ vn 0.854010 -0.382713 -0.352416
1371
+ vn 0.768848 -0.382713 -0.512254
1372
+ vn 0.654139 -0.382713 -0.652406
1373
+ vn 0.514292 -0.382713 -0.767486
1374
+ vn 0.354681 -0.382713 -0.853072
1375
+ vn 0.181440 -0.382713 -0.905875
1376
+ vn 0.001784 -0.555605 -0.831445
1377
+ vn -0.160456 -0.555605 -0.815817
1378
+ vn -0.316531 -0.555605 -0.768838
1379
+ vn -0.460442 -0.555605 -0.692312
1380
+ vn -0.586658 -0.555605 -0.589182
1381
+ vn -0.690329 -0.555605 -0.463410
1382
+ vn -0.767472 -0.555605 -0.319829
1383
+ vn -0.815121 -0.555605 -0.163957
1384
+ vn -0.831445 -0.555605 -0.001784
1385
+ vn -0.815817 -0.555605 0.160457
1386
+ vn -0.768837 -0.555605 0.316532
1387
+ vn -0.692312 -0.555605 0.460442
1388
+ vn -0.589182 -0.555605 0.586659
1389
+ vn -0.463409 -0.555605 0.690330
1390
+ vn -0.319828 -0.555605 0.767472
1391
+ vn -0.163956 -0.555605 0.815121
1392
+ vn -0.001784 -0.555605 0.831445
1393
+ vn 0.160457 -0.555605 0.815817
1394
+ vn 0.316532 -0.555605 0.768837
1395
+ vn 0.460443 -0.555605 0.692312
1396
+ vn 0.586659 -0.555605 0.589181
1397
+ vn 0.690330 -0.555605 0.463409
1398
+ vn 0.767472 -0.555605 0.319828
1399
+ vn 0.815121 -0.555605 0.163956
1400
+ vn 0.831445 -0.555605 0.001783
1401
+ vn 0.815816 -0.555605 -0.160458
1402
+ vn 0.768837 -0.555605 -0.316533
1403
+ vn 0.692312 -0.555605 -0.460443
1404
+ vn 0.589181 -0.555605 -0.586659
1405
+ vn 0.463408 -0.555605 -0.690330
1406
+ vn 0.319827 -0.555605 -0.767472
1407
+ vn 0.163956 -0.555605 -0.815121
1408
+ vn 0.002275 -0.707138 -0.707072
1409
+ vn -0.135711 -0.707138 -0.693930
1410
+ vn -0.268483 -0.707138 -0.654120
1411
+ vn -0.390936 -0.707138 -0.589173
1412
+ vn -0.498367 -0.707138 -0.501585
1413
+ vn -0.586645 -0.707138 -0.394720
1414
+ vn -0.652379 -0.707138 -0.272687
1415
+ vn -0.693042 -0.707138 -0.140175
1416
+ vn -0.707072 -0.707138 -0.002275
1417
+ vn -0.693930 -0.707138 0.135711
1418
+ vn -0.654120 -0.707138 0.268483
1419
+ vn -0.589173 -0.707138 0.390936
1420
+ vn -0.501584 -0.707138 0.498367
1421
+ vn -0.394720 -0.707138 0.586645
1422
+ vn -0.272687 -0.707138 0.652379
1423
+ vn -0.140174 -0.707138 0.693042
1424
+ vn -0.002275 -0.707138 0.707072
1425
+ vn 0.135712 -0.707138 0.693930
1426
+ vn 0.268483 -0.707138 0.654120
1427
+ vn 0.390937 -0.707138 0.589173
1428
+ vn 0.498367 -0.707138 0.501584
1429
+ vn 0.586645 -0.707138 0.394719
1430
+ vn 0.652379 -0.707138 0.272686
1431
+ vn 0.693042 -0.707138 0.140174
1432
+ vn 0.707072 -0.707138 0.002274
1433
+ vn 0.693930 -0.707138 -0.135712
1434
+ vn 0.654120 -0.707138 -0.268484
1435
+ vn 0.589173 -0.707138 -0.390937
1436
+ vn 0.501584 -0.707138 -0.498367
1437
+ vn 0.394719 -0.707138 -0.586646
1438
+ vn 0.272686 -0.707138 -0.652379
1439
+ vn 0.140174 -0.707138 -0.693042
1440
+ vn 0.002680 -0.831490 -0.555533
1441
+ vn -0.105750 -0.831490 -0.545381
1442
+ vn -0.210117 -0.831490 -0.514271
1443
+ vn -0.306408 -0.831490 -0.463398
1444
+ vn -0.390925 -0.831490 -0.394716
1445
+ vn -0.460419 -0.831490 -0.310866
1446
+ vn -0.512219 -0.831490 -0.215070
1447
+ vn -0.544335 -0.831490 -0.111008
1448
+ vn -0.555533 -0.831490 -0.002680
1449
+ vn -0.545381 -0.831490 0.105750
1450
+ vn -0.514271 -0.831490 0.210117
1451
+ vn -0.463398 -0.831490 0.306409
1452
+ vn -0.394716 -0.831490 0.390926
1453
+ vn -0.310866 -0.831490 0.460419
1454
+ vn -0.215069 -0.831491 0.512219
1455
+ vn -0.111008 -0.831490 0.544335
1456
+ vn -0.002680 -0.831490 0.555533
1457
+ vn 0.105750 -0.831490 0.545381
1458
+ vn 0.210117 -0.831490 0.514271
1459
+ vn 0.306409 -0.831490 0.463397
1460
+ vn 0.390926 -0.831490 0.394716
1461
+ vn 0.460420 -0.831490 0.310866
1462
+ vn 0.512220 -0.831490 0.215069
1463
+ vn 0.544335 -0.831490 0.111007
1464
+ vn 0.555533 -0.831490 0.002680
1465
+ vn 0.545381 -0.831490 -0.105751
1466
+ vn 0.514271 -0.831490 -0.210117
1467
+ vn 0.463397 -0.831491 -0.306409
1468
+ vn 0.394716 -0.831491 -0.390926
1469
+ vn 0.310865 -0.831490 -0.460420
1470
+ vn 0.215069 -0.831490 -0.512220
1471
+ vn 0.111007 -0.831490 -0.544335
1472
+ vn 0.002983 -0.923888 -0.382651
1473
+ vn -0.071726 -0.923888 -0.375880
1474
+ vn -0.143678 -0.923888 -0.354665
1475
+ vn -0.210109 -0.923888 -0.319820
1476
+ vn -0.268466 -0.923888 -0.272685
1477
+ vn -0.316505 -0.923888 -0.215070
1478
+ vn -0.352382 -0.923888 -0.149190
1479
+ vn -0.374717 -0.923888 -0.077577
1480
+ vn -0.382651 -0.923888 -0.002983
1481
+ vn -0.375880 -0.923888 0.071726
1482
+ vn -0.354665 -0.923888 0.143678
1483
+ vn -0.319820 -0.923888 0.210109
1484
+ vn -0.272684 -0.923888 0.268466
1485
+ vn -0.215070 -0.923888 0.316506
1486
+ vn -0.149190 -0.923888 0.352382
1487
+ vn -0.077577 -0.923888 0.374717
1488
+ vn -0.002983 -0.923888 0.382651
1489
+ vn 0.071726 -0.923888 0.375880
1490
+ vn 0.143679 -0.923888 0.354665
1491
+ vn 0.210109 -0.923888 0.319820
1492
+ vn 0.268466 -0.923888 0.272684
1493
+ vn 0.316506 -0.923888 0.215069
1494
+ vn 0.352382 -0.923888 0.149190
1495
+ vn 0.374717 -0.923888 0.077577
1496
+ vn 0.382651 -0.923888 0.002983
1497
+ vn 0.375880 -0.923888 -0.071726
1498
+ vn 0.354665 -0.923888 -0.143679
1499
+ vn 0.319820 -0.923888 -0.210110
1500
+ vn 0.272684 -0.923888 -0.268466
1501
+ vn 0.215069 -0.923888 -0.316506
1502
+ vn 0.149190 -0.923888 -0.352382
1503
+ vn 0.077577 -0.923888 -0.374717
1504
+ vn 0.005744 -0.976740 -0.214348
1505
+ vn -0.036184 -0.976740 -0.211350
1506
+ vn -0.076721 -0.976740 -0.200230
1507
+ vn -0.114310 -0.976740 -0.181415
1508
+ vn -0.147505 -0.976740 -0.155628
1509
+ vn -0.175033 -0.976740 -0.123861
1510
+ vn -0.195834 -0.976740 -0.087334
1511
+ vn -0.209109 -0.976740 -0.047451
1512
+ vn -0.214348 -0.976740 -0.005744
1513
+ vn -0.211350 -0.976740 0.036184
1514
+ vn -0.200230 -0.976740 0.076721
1515
+ vn -0.181415 -0.976740 0.114310
1516
+ vn -0.155628 -0.976740 0.147506
1517
+ vn -0.123861 -0.976740 0.175033
1518
+ vn -0.087334 -0.976740 0.195834
1519
+ vn -0.047450 -0.976740 0.209109
1520
+ vn -0.005744 -0.976740 0.214348
1521
+ vn 0.036184 -0.976740 0.211350
1522
+ vn 0.076721 -0.976740 0.200230
1523
+ vn 0.114310 -0.976740 0.181415
1524
+ vn 0.147506 -0.976740 0.155628
1525
+ vn 0.175033 -0.976740 0.123861
1526
+ vn 0.195834 -0.976740 0.087334
1527
+ vn 0.209109 -0.976740 0.047450
1528
+ vn 0.214348 -0.976740 0.005743
1529
+ vn 0.211350 -0.976740 -0.036184
1530
+ vn 0.200230 -0.976740 -0.076721
1531
+ vn 0.181415 -0.976740 -0.114310
1532
+ vn 0.155628 -0.976740 -0.147506
1533
+ vn 0.123861 -0.976740 -0.175033
1534
+ vn 0.087334 -0.976740 -0.195834
1535
+ vn 0.047450 -0.976740 -0.209109
1536
+ vn 0.000000 -1.000000 -0.000000
1537
+ # 482 vertex normals
1538
+
1539
+ g default
1540
+ s 1
1541
+ f 1/1/1 2/34/2 3/35/3
1542
+ f 1/2/1 3/35/3 4/36/4
1543
+ f 1/3/1 4/36/4 5/37/5
1544
+ f 1/4/1 5/37/5 6/38/6
1545
+ f 1/5/1 6/38/6 7/39/7
1546
+ f 1/6/1 7/39/7 8/40/8
1547
+ f 1/7/1 8/40/8 9/41/9
1548
+ f 1/8/1 9/41/9 10/42/10
1549
+ f 1/9/1 10/42/10 11/43/11
1550
+ f 1/10/1 11/43/11 12/44/12
1551
+ f 1/11/1 12/44/12 13/45/13
1552
+ f 1/12/1 13/45/13 14/46/14
1553
+ f 1/13/1 14/46/14 15/47/15
1554
+ f 1/14/1 15/47/15 16/48/16
1555
+ f 1/15/1 16/48/16 17/49/17
1556
+ f 1/16/1 17/49/17 18/50/18
1557
+ f 1/17/1 18/50/18 19/51/19
1558
+ f 1/18/1 19/51/19 20/52/20
1559
+ f 1/19/1 20/52/20 21/53/21
1560
+ f 1/20/1 21/53/21 22/54/22
1561
+ f 1/21/1 22/54/22 23/55/23
1562
+ f 1/22/1 23/55/23 24/56/24
1563
+ f 1/23/1 24/56/24 25/57/25
1564
+ f 1/24/1 25/57/25 26/58/26
1565
+ f 1/25/1 26/58/26 27/59/27
1566
+ f 1/26/1 27/59/27 28/60/28
1567
+ f 1/27/1 28/60/28 29/61/29
1568
+ f 1/28/1 29/61/29 30/62/30
1569
+ f 1/29/1 30/62/30 31/63/31
1570
+ f 1/30/1 31/63/31 32/64/32
1571
+ f 1/31/1 32/64/32 33/65/33
1572
+ f 1/32/1 33/65/33 2/66/2
1573
+ f 2/34/2 34/67/34 35/68/35
1574
+ f 2/34/2 35/68/35 3/35/3
1575
+ f 3/35/3 35/68/35 36/69/36
1576
+ f 3/35/3 36/69/36 4/36/4
1577
+ f 4/36/4 36/69/36 37/70/37
1578
+ f 4/36/4 37/70/37 5/37/5
1579
+ f 5/37/5 37/70/37 38/71/38
1580
+ f 5/37/5 38/71/38 6/38/6
1581
+ f 6/38/6 38/71/38 39/72/39
1582
+ f 6/38/6 39/72/39 7/39/7
1583
+ f 7/39/7 39/72/39 40/73/40
1584
+ f 7/39/7 40/73/40 8/40/8
1585
+ f 8/40/8 40/73/40 41/74/41
1586
+ f 8/40/8 41/74/41 9/41/9
1587
+ f 9/41/9 41/74/41 42/75/42
1588
+ f 9/41/9 42/75/42 10/42/10
1589
+ f 10/42/10 42/75/42 43/76/43
1590
+ f 10/42/10 43/76/43 11/43/11
1591
+ f 11/43/11 43/76/43 44/77/44
1592
+ f 11/43/11 44/77/44 12/44/12
1593
+ f 12/44/12 44/77/44 45/78/45
1594
+ f 12/44/12 45/78/45 13/45/13
1595
+ f 13/45/13 45/78/45 46/79/46
1596
+ f 13/45/13 46/79/46 14/46/14
1597
+ f 14/46/14 46/79/46 47/80/47
1598
+ f 14/46/14 47/80/47 15/47/15
1599
+ f 15/47/15 47/80/47 48/81/48
1600
+ f 15/47/15 48/81/48 16/48/16
1601
+ f 16/48/16 48/81/48 49/82/49
1602
+ f 16/48/16 49/82/49 17/49/17
1603
+ f 17/49/17 49/82/49 50/83/50
1604
+ f 17/49/17 50/83/50 18/50/18
1605
+ f 18/50/18 50/83/50 51/84/51
1606
+ f 18/50/18 51/84/51 19/51/19
1607
+ f 19/51/19 51/84/51 52/85/52
1608
+ f 19/51/19 52/85/52 20/52/20
1609
+ f 20/52/20 52/85/52 53/86/53
1610
+ f 20/52/20 53/86/53 21/53/21
1611
+ f 21/53/21 53/86/53 54/87/54
1612
+ f 21/53/21 54/87/54 22/54/22
1613
+ f 22/54/22 54/87/54 55/88/55
1614
+ f 22/54/22 55/88/55 23/55/23
1615
+ f 23/55/23 55/88/55 56/89/56
1616
+ f 23/55/23 56/89/56 24/56/24
1617
+ f 24/56/24 56/89/56 57/90/57
1618
+ f 24/56/24 57/90/57 25/57/25
1619
+ f 25/57/25 57/90/57 58/91/58
1620
+ f 25/57/25 58/91/58 26/58/26
1621
+ f 26/58/26 58/91/58 59/92/59
1622
+ f 26/58/26 59/92/59 27/59/27
1623
+ f 27/59/27 59/92/59 60/93/60
1624
+ f 27/59/27 60/93/60 28/60/28
1625
+ f 28/60/28 60/93/60 61/94/61
1626
+ f 28/60/28 61/94/61 29/61/29
1627
+ f 29/61/29 61/94/61 62/95/62
1628
+ f 29/61/29 62/95/62 30/62/30
1629
+ f 30/62/30 62/95/62 63/96/63
1630
+ f 30/62/30 63/96/63 31/63/31
1631
+ f 31/63/31 63/96/63 64/97/64
1632
+ f 31/63/31 64/97/64 32/64/32
1633
+ f 32/64/32 64/97/64 65/98/65
1634
+ f 32/64/32 65/98/65 33/65/33
1635
+ f 33/65/33 65/98/65 34/99/34
1636
+ f 33/65/33 34/99/34 2/66/2
1637
+ f 34/67/34 66/100/66 67/101/67
1638
+ f 34/67/34 67/101/67 35/68/35
1639
+ f 35/68/35 67/101/67 68/102/68
1640
+ f 35/68/35 68/102/68 36/69/36
1641
+ f 36/69/36 68/102/68 69/103/69
1642
+ f 36/69/36 69/103/69 37/70/37
1643
+ f 37/70/37 69/103/69 70/104/70
1644
+ f 37/70/37 70/104/70 38/71/38
1645
+ f 38/71/38 70/104/70 71/105/71
1646
+ f 38/71/38 71/105/71 39/72/39
1647
+ f 39/72/39 71/105/71 72/106/72
1648
+ f 39/72/39 72/106/72 40/73/40
1649
+ f 40/73/40 72/106/72 73/107/73
1650
+ f 40/73/40 73/107/73 41/74/41
1651
+ f 41/74/41 73/107/73 74/108/74
1652
+ f 41/74/41 74/108/74 42/75/42
1653
+ f 42/75/42 74/108/74 75/109/75
1654
+ f 42/75/42 75/109/75 43/76/43
1655
+ f 43/76/43 75/109/75 76/110/76
1656
+ f 43/76/43 76/110/76 44/77/44
1657
+ f 44/77/44 76/110/76 77/111/77
1658
+ f 44/77/44 77/111/77 45/78/45
1659
+ f 45/78/45 77/111/77 78/112/78
1660
+ f 45/78/45 78/112/78 46/79/46
1661
+ f 46/79/46 78/112/78 79/113/79
1662
+ f 46/79/46 79/113/79 47/80/47
1663
+ f 47/80/47 79/113/79 80/114/80
1664
+ f 47/80/47 80/114/80 48/81/48
1665
+ f 48/81/48 80/114/80 81/115/81
1666
+ f 48/81/48 81/115/81 49/82/49
1667
+ f 49/82/49 81/115/81 82/116/82
1668
+ f 49/82/49 82/116/82 50/83/50
1669
+ f 50/83/50 82/116/82 83/117/83
1670
+ f 50/83/50 83/117/83 51/84/51
1671
+ f 51/84/51 83/117/83 84/118/84
1672
+ f 51/84/51 84/118/84 52/85/52
1673
+ f 52/85/52 84/118/84 85/119/85
1674
+ f 52/85/52 85/119/85 53/86/53
1675
+ f 53/86/53 85/119/85 86/120/86
1676
+ f 53/86/53 86/120/86 54/87/54
1677
+ f 54/87/54 86/120/86 87/121/87
1678
+ f 54/87/54 87/121/87 55/88/55
1679
+ f 55/88/55 87/121/87 88/122/88
1680
+ f 55/88/55 88/122/88 56/89/56
1681
+ f 56/89/56 88/122/88 89/123/89
1682
+ f 56/89/56 89/123/89 57/90/57
1683
+ f 57/90/57 89/123/89 90/124/90
1684
+ f 57/90/57 90/124/90 58/91/58
1685
+ f 58/91/58 90/124/90 91/125/91
1686
+ f 58/91/58 91/125/91 59/92/59
1687
+ f 59/92/59 91/125/91 92/126/92
1688
+ f 59/92/59 92/126/92 60/93/60
1689
+ f 60/93/60 92/126/92 93/127/93
1690
+ f 60/93/60 93/127/93 61/94/61
1691
+ f 61/94/61 93/127/93 94/128/94
1692
+ f 61/94/61 94/128/94 62/95/62
1693
+ f 62/95/62 94/128/94 95/129/95
1694
+ f 62/95/62 95/129/95 63/96/63
1695
+ f 63/96/63 95/129/95 96/130/96
1696
+ f 63/96/63 96/130/96 64/97/64
1697
+ f 64/97/64 96/130/96 97/131/97
1698
+ f 64/97/64 97/131/97 65/98/65
1699
+ f 65/98/65 97/131/97 66/132/66
1700
+ f 65/98/65 66/132/66 34/99/34
1701
+ f 66/100/66 98/133/98 99/134/99
1702
+ f 66/100/66 99/134/99 67/101/67
1703
+ f 67/101/67 99/134/99 100/135/100
1704
+ f 67/101/67 100/135/100 68/102/68
1705
+ f 68/102/68 100/135/100 101/136/101
1706
+ f 68/102/68 101/136/101 69/103/69
1707
+ f 69/103/69 101/136/101 102/137/102
1708
+ f 69/103/69 102/137/102 70/104/70
1709
+ f 70/104/70 102/137/102 103/138/103
1710
+ f 70/104/70 103/138/103 71/105/71
1711
+ f 71/105/71 103/138/103 104/139/104
1712
+ f 71/105/71 104/139/104 72/106/72
1713
+ f 72/106/72 104/139/104 105/140/105
1714
+ f 72/106/72 105/140/105 73/107/73
1715
+ f 73/107/73 105/140/105 106/141/106
1716
+ f 73/107/73 106/141/106 74/108/74
1717
+ f 74/108/74 106/141/106 107/142/107
1718
+ f 74/108/74 107/142/107 75/109/75
1719
+ f 75/109/75 107/142/107 108/143/108
1720
+ f 75/109/75 108/143/108 76/110/76
1721
+ f 76/110/76 108/143/108 109/144/109
1722
+ f 76/110/76 109/144/109 77/111/77
1723
+ f 77/111/77 109/144/109 110/145/110
1724
+ f 77/111/77 110/145/110 78/112/78
1725
+ f 78/112/78 110/145/110 111/146/111
1726
+ f 78/112/78 111/146/111 79/113/79
1727
+ f 79/113/79 111/146/111 112/147/112
1728
+ f 79/113/79 112/147/112 80/114/80
1729
+ f 80/114/80 112/147/112 113/148/113
1730
+ f 80/114/80 113/148/113 81/115/81
1731
+ f 81/115/81 113/148/113 114/149/114
1732
+ f 81/115/81 114/149/114 82/116/82
1733
+ f 82/116/82 114/149/114 115/150/115
1734
+ f 82/116/82 115/150/115 83/117/83
1735
+ f 83/117/83 115/150/115 116/151/116
1736
+ f 83/117/83 116/151/116 84/118/84
1737
+ f 84/118/84 116/151/116 117/152/117
1738
+ f 84/118/84 117/152/117 85/119/85
1739
+ f 85/119/85 117/152/117 118/153/118
1740
+ f 85/119/85 118/153/118 86/120/86
1741
+ f 86/120/86 118/153/118 119/154/119
1742
+ f 86/120/86 119/154/119 87/121/87
1743
+ f 87/121/87 119/154/119 120/155/120
1744
+ f 87/121/87 120/155/120 88/122/88
1745
+ f 88/122/88 120/155/120 121/156/121
1746
+ f 88/122/88 121/156/121 89/123/89
1747
+ f 89/123/89 121/156/121 122/157/122
1748
+ f 89/123/89 122/157/122 90/124/90
1749
+ f 90/124/90 122/157/122 123/158/123
1750
+ f 90/124/90 123/158/123 91/125/91
1751
+ f 91/125/91 123/158/123 124/159/124
1752
+ f 91/125/91 124/159/124 92/126/92
1753
+ f 92/126/92 124/159/124 125/160/125
1754
+ f 92/126/92 125/160/125 93/127/93
1755
+ f 93/127/93 125/160/125 126/161/126
1756
+ f 93/127/93 126/161/126 94/128/94
1757
+ f 94/128/94 126/161/126 127/162/127
1758
+ f 94/128/94 127/162/127 95/129/95
1759
+ f 95/129/95 127/162/127 128/163/128
1760
+ f 95/129/95 128/163/128 96/130/96
1761
+ f 96/130/96 128/163/128 129/164/129
1762
+ f 96/130/96 129/164/129 97/131/97
1763
+ f 97/131/97 129/164/129 98/165/98
1764
+ f 97/131/97 98/165/98 66/132/66
1765
+ f 98/133/98 130/166/130 131/167/131
1766
+ f 98/133/98 131/167/131 99/134/99
1767
+ f 99/134/99 131/167/131 132/168/132
1768
+ f 99/134/99 132/168/132 100/135/100
1769
+ f 100/135/100 132/168/132 133/169/133
1770
+ f 100/135/100 133/169/133 101/136/101
1771
+ f 101/136/101 133/169/133 134/170/134
1772
+ f 101/136/101 134/170/134 102/137/102
1773
+ f 102/137/102 134/170/134 135/171/135
1774
+ f 102/137/102 135/171/135 103/138/103
1775
+ f 103/138/103 135/171/135 136/172/136
1776
+ f 103/138/103 136/172/136 104/139/104
1777
+ f 104/139/104 136/172/136 137/173/137
1778
+ f 104/139/104 137/173/137 105/140/105
1779
+ f 105/140/105 137/173/137 138/174/138
1780
+ f 105/140/105 138/174/138 106/141/106
1781
+ f 106/141/106 138/174/138 139/175/139
1782
+ f 106/141/106 139/175/139 107/142/107
1783
+ f 107/142/107 139/175/139 140/176/140
1784
+ f 107/142/107 140/176/140 108/143/108
1785
+ f 108/143/108 140/176/140 141/177/141
1786
+ f 108/143/108 141/177/141 109/144/109
1787
+ f 109/144/109 141/177/141 142/178/142
1788
+ f 109/144/109 142/178/142 110/145/110
1789
+ f 110/145/110 142/178/142 143/179/143
1790
+ f 110/145/110 143/179/143 111/146/111
1791
+ f 111/146/111 143/179/143 144/180/144
1792
+ f 111/146/111 144/180/144 112/147/112
1793
+ f 112/147/112 144/180/144 145/181/145
1794
+ f 112/147/112 145/181/145 113/148/113
1795
+ f 113/148/113 145/181/145 146/182/146
1796
+ f 113/148/113 146/182/146 114/149/114
1797
+ f 114/149/114 146/182/146 147/183/147
1798
+ f 114/149/114 147/183/147 115/150/115
1799
+ f 115/150/115 147/183/147 148/184/148
1800
+ f 115/150/115 148/184/148 116/151/116
1801
+ f 116/151/116 148/184/148 149/185/149
1802
+ f 116/151/116 149/185/149 117/152/117
1803
+ f 117/152/117 149/185/149 150/186/150
1804
+ f 117/152/117 150/186/150 118/153/118
1805
+ f 118/153/118 150/186/150 151/187/151
1806
+ f 118/153/118 151/187/151 119/154/119
1807
+ f 119/154/119 151/187/151 152/188/152
1808
+ f 119/154/119 152/188/152 120/155/120
1809
+ f 120/155/120 152/188/152 153/189/153
1810
+ f 120/155/120 153/189/153 121/156/121
1811
+ f 121/156/121 153/189/153 154/190/154
1812
+ f 121/156/121 154/190/154 122/157/122
1813
+ f 122/157/122 154/190/154 155/191/155
1814
+ f 122/157/122 155/191/155 123/158/123
1815
+ f 123/158/123 155/191/155 156/192/156
1816
+ f 123/158/123 156/192/156 124/159/124
1817
+ f 124/159/124 156/192/156 157/193/157
1818
+ f 124/159/124 157/193/157 125/160/125
1819
+ f 125/160/125 157/193/157 158/194/158
1820
+ f 125/160/125 158/194/158 126/161/126
1821
+ f 126/161/126 158/194/158 159/195/159
1822
+ f 126/161/126 159/195/159 127/162/127
1823
+ f 127/162/127 159/195/159 160/196/160
1824
+ f 127/162/127 160/196/160 128/163/128
1825
+ f 128/163/128 160/196/160 161/197/161
1826
+ f 128/163/128 161/197/161 129/164/129
1827
+ f 129/164/129 161/197/161 130/198/130
1828
+ f 129/164/129 130/198/130 98/165/98
1829
+ f 130/166/130 162/199/162 163/200/163
1830
+ f 130/166/130 163/200/163 131/167/131
1831
+ f 131/167/131 163/200/163 164/201/164
1832
+ f 131/167/131 164/201/164 132/168/132
1833
+ f 132/168/132 164/201/164 165/202/165
1834
+ f 132/168/132 165/202/165 133/169/133
1835
+ f 133/169/133 165/202/165 166/203/166
1836
+ f 133/169/133 166/203/166 134/170/134
1837
+ f 134/170/134 166/203/166 167/204/167
1838
+ f 134/170/134 167/204/167 135/171/135
1839
+ f 135/171/135 167/204/167 168/205/168
1840
+ f 135/171/135 168/205/168 136/172/136
1841
+ f 136/172/136 168/205/168 169/206/169
1842
+ f 136/172/136 169/206/169 137/173/137
1843
+ f 137/173/137 169/206/169 170/207/170
1844
+ f 137/173/137 170/207/170 138/174/138
1845
+ f 138/174/138 170/207/170 171/208/171
1846
+ f 138/174/138 171/208/171 139/175/139
1847
+ f 139/175/139 171/208/171 172/209/172
1848
+ f 139/175/139 172/209/172 140/176/140
1849
+ f 140/176/140 172/209/172 173/210/173
1850
+ f 140/176/140 173/210/173 141/177/141
1851
+ f 141/177/141 173/210/173 174/211/174
1852
+ f 141/177/141 174/211/174 142/178/142
1853
+ f 142/178/142 174/211/174 175/212/175
1854
+ f 142/178/142 175/212/175 143/179/143
1855
+ f 143/179/143 175/212/175 176/213/176
1856
+ f 143/179/143 176/213/176 144/180/144
1857
+ f 144/180/144 176/213/176 177/214/177
1858
+ f 144/180/144 177/214/177 145/181/145
1859
+ f 145/181/145 177/214/177 178/215/178
1860
+ f 145/181/145 178/215/178 146/182/146
1861
+ f 146/182/146 178/215/178 179/216/179
1862
+ f 146/182/146 179/216/179 147/183/147
1863
+ f 147/183/147 179/216/179 180/217/180
1864
+ f 147/183/147 180/217/180 148/184/148
1865
+ f 148/184/148 180/217/180 181/218/181
1866
+ f 148/184/148 181/218/181 149/185/149
1867
+ f 149/185/149 181/218/181 182/219/182
1868
+ f 149/185/149 182/219/182 150/186/150
1869
+ f 150/186/150 182/219/182 183/220/183
1870
+ f 150/186/150 183/220/183 151/187/151
1871
+ f 151/187/151 183/220/183 184/221/184
1872
+ f 151/187/151 184/221/184 152/188/152
1873
+ f 152/188/152 184/221/184 185/222/185
1874
+ f 152/188/152 185/222/185 153/189/153
1875
+ f 153/189/153 185/222/185 186/223/186
1876
+ f 153/189/153 186/223/186 154/190/154
1877
+ f 154/190/154 186/223/186 187/224/187
1878
+ f 154/190/154 187/224/187 155/191/155
1879
+ f 155/191/155 187/224/187 188/225/188
1880
+ f 155/191/155 188/225/188 156/192/156
1881
+ f 156/192/156 188/225/188 189/226/189
1882
+ f 156/192/156 189/226/189 157/193/157
1883
+ f 157/193/157 189/226/189 190/227/190
1884
+ f 157/193/157 190/227/190 158/194/158
1885
+ f 158/194/158 190/227/190 191/228/191
1886
+ f 158/194/158 191/228/191 159/195/159
1887
+ f 159/195/159 191/228/191 192/229/192
1888
+ f 159/195/159 192/229/192 160/196/160
1889
+ f 160/196/160 192/229/192 193/230/193
1890
+ f 160/196/160 193/230/193 161/197/161
1891
+ f 161/197/161 193/230/193 162/231/162
1892
+ f 161/197/161 162/231/162 130/198/130
1893
+ f 162/199/162 194/232/194 195/233/195
1894
+ f 162/199/162 195/233/195 163/200/163
1895
+ f 163/200/163 195/233/195 196/234/196
1896
+ f 163/200/163 196/234/196 164/201/164
1897
+ f 164/201/164 196/234/196 197/235/197
1898
+ f 164/201/164 197/235/197 165/202/165
1899
+ f 165/202/165 197/235/197 198/236/198
1900
+ f 165/202/165 198/236/198 166/203/166
1901
+ f 166/203/166 198/236/198 199/237/199
1902
+ f 166/203/166 199/237/199 167/204/167
1903
+ f 167/204/167 199/237/199 200/238/200
1904
+ f 167/204/167 200/238/200 168/205/168
1905
+ f 168/205/168 200/238/200 201/239/201
1906
+ f 168/205/168 201/239/201 169/206/169
1907
+ f 169/206/169 201/239/201 202/240/202
1908
+ f 169/206/169 202/240/202 170/207/170
1909
+ f 170/207/170 202/240/202 203/241/203
1910
+ f 170/207/170 203/241/203 171/208/171
1911
+ f 171/208/171 203/241/203 204/242/204
1912
+ f 171/208/171 204/242/204 172/209/172
1913
+ f 172/209/172 204/242/204 205/243/205
1914
+ f 172/209/172 205/243/205 173/210/173
1915
+ f 173/210/173 205/243/205 206/244/206
1916
+ f 173/210/173 206/244/206 174/211/174
1917
+ f 174/211/174 206/244/206 207/245/207
1918
+ f 174/211/174 207/245/207 175/212/175
1919
+ f 175/212/175 207/245/207 208/246/208
1920
+ f 175/212/175 208/246/208 176/213/176
1921
+ f 176/213/176 208/246/208 209/247/209
1922
+ f 176/213/176 209/247/209 177/214/177
1923
+ f 177/214/177 209/247/209 210/248/210
1924
+ f 177/214/177 210/248/210 178/215/178
1925
+ f 178/215/178 210/248/210 211/249/211
1926
+ f 178/215/178 211/249/211 179/216/179
1927
+ f 179/216/179 211/249/211 212/250/212
1928
+ f 179/216/179 212/250/212 180/217/180
1929
+ f 180/217/180 212/250/212 213/251/213
1930
+ f 180/217/180 213/251/213 181/218/181
1931
+ f 181/218/181 213/251/213 214/252/214
1932
+ f 181/218/181 214/252/214 182/219/182
1933
+ f 182/219/182 214/252/214 215/253/215
1934
+ f 182/219/182 215/253/215 183/220/183
1935
+ f 183/220/183 215/253/215 216/254/216
1936
+ f 183/220/183 216/254/216 184/221/184
1937
+ f 184/221/184 216/254/216 217/255/217
1938
+ f 184/221/184 217/255/217 185/222/185
1939
+ f 185/222/185 217/255/217 218/256/218
1940
+ f 185/222/185 218/256/218 186/223/186
1941
+ f 186/223/186 218/256/218 219/257/219
1942
+ f 186/223/186 219/257/219 187/224/187
1943
+ f 187/224/187 219/257/219 220/258/220
1944
+ f 187/224/187 220/258/220 188/225/188
1945
+ f 188/225/188 220/258/220 221/259/221
1946
+ f 188/225/188 221/259/221 189/226/189
1947
+ f 189/226/189 221/259/221 222/260/222
1948
+ f 189/226/189 222/260/222 190/227/190
1949
+ f 190/227/190 222/260/222 223/261/223
1950
+ f 190/227/190 223/261/223 191/228/191
1951
+ f 191/228/191 223/261/223 224/262/224
1952
+ f 191/228/191 224/262/224 192/229/192
1953
+ f 192/229/192 224/262/224 225/263/225
1954
+ f 192/229/192 225/263/225 193/230/193
1955
+ f 193/230/193 225/263/225 194/264/194
1956
+ f 193/230/193 194/264/194 162/231/162
1957
+ f 194/232/194 226/265/226 227/266/227
1958
+ f 194/232/194 227/266/227 195/233/195
1959
+ f 195/233/195 227/266/227 228/267/228
1960
+ f 195/233/195 228/267/228 196/234/196
1961
+ f 196/234/196 228/267/228 229/268/229
1962
+ f 196/234/196 229/268/229 197/235/197
1963
+ f 197/235/197 229/268/229 230/269/230
1964
+ f 197/235/197 230/269/230 198/236/198
1965
+ f 198/236/198 230/269/230 231/270/231
1966
+ f 198/236/198 231/270/231 199/237/199
1967
+ f 199/237/199 231/270/231 232/271/232
1968
+ f 199/237/199 232/271/232 200/238/200
1969
+ f 200/238/200 232/271/232 233/272/233
1970
+ f 200/238/200 233/272/233 201/239/201
1971
+ f 201/239/201 233/272/233 234/273/234
1972
+ f 201/239/201 234/273/234 202/240/202
1973
+ f 202/240/202 234/273/234 235/274/235
1974
+ f 202/240/202 235/274/235 203/241/203
1975
+ f 203/241/203 235/274/235 236/275/236
1976
+ f 203/241/203 236/275/236 204/242/204
1977
+ f 204/242/204 236/275/236 237/276/237
1978
+ f 204/242/204 237/276/237 205/243/205
1979
+ f 205/243/205 237/276/237 238/277/238
1980
+ f 205/243/205 238/277/238 206/244/206
1981
+ f 206/244/206 238/277/238 239/278/239
1982
+ f 206/244/206 239/278/239 207/245/207
1983
+ f 207/245/207 239/278/239 240/279/240
1984
+ f 207/245/207 240/279/240 208/246/208
1985
+ f 208/246/208 240/279/240 241/280/241
1986
+ f 208/246/208 241/280/241 209/247/209
1987
+ f 209/247/209 241/280/241 242/281/242
1988
+ f 209/247/209 242/281/242 210/248/210
1989
+ f 210/248/210 242/281/242 243/282/243
1990
+ f 210/248/210 243/282/243 211/249/211
1991
+ f 211/249/211 243/282/243 244/283/244
1992
+ f 211/249/211 244/283/244 212/250/212
1993
+ f 212/250/212 244/283/244 245/284/245
1994
+ f 212/250/212 245/284/245 213/251/213
1995
+ f 213/251/213 245/284/245 246/285/246
1996
+ f 213/251/213 246/285/246 214/252/214
1997
+ f 214/252/214 246/285/246 247/286/247
1998
+ f 214/252/214 247/286/247 215/253/215
1999
+ f 215/253/215 247/286/247 248/287/248
2000
+ f 215/253/215 248/287/248 216/254/216
2001
+ f 216/254/216 248/287/248 249/288/249
2002
+ f 216/254/216 249/288/249 217/255/217
2003
+ f 217/255/217 249/288/249 250/289/250
2004
+ f 217/255/217 250/289/250 218/256/218
2005
+ f 218/256/218 250/289/250 251/290/251
2006
+ f 218/256/218 251/290/251 219/257/219
2007
+ f 219/257/219 251/290/251 252/291/252
2008
+ f 219/257/219 252/291/252 220/258/220
2009
+ f 220/258/220 252/291/252 253/292/253
2010
+ f 220/258/220 253/292/253 221/259/221
2011
+ f 221/259/221 253/292/253 254/293/254
2012
+ f 221/259/221 254/293/254 222/260/222
2013
+ f 222/260/222 254/293/254 255/294/255
2014
+ f 222/260/222 255/294/255 223/261/223
2015
+ f 223/261/223 255/294/255 256/295/256
2016
+ f 223/261/223 256/295/256 224/262/224
2017
+ f 224/262/224 256/295/256 257/296/257
2018
+ f 224/262/224 257/296/257 225/263/225
2019
+ f 225/263/225 257/296/257 226/297/226
2020
+ f 225/263/225 226/297/226 194/264/194
2021
+ f 226/265/226 258/298/258 259/299/259
2022
+ f 226/265/226 259/299/259 227/266/227
2023
+ f 227/266/227 259/299/259 260/300/260
2024
+ f 227/266/227 260/300/260 228/267/228
2025
+ f 228/267/228 260/300/260 261/301/261
2026
+ f 228/267/228 261/301/261 229/268/229
2027
+ f 229/268/229 261/301/261 262/302/262
2028
+ f 229/268/229 262/302/262 230/269/230
2029
+ f 230/269/230 262/302/262 263/303/263
2030
+ f 230/269/230 263/303/263 231/270/231
2031
+ f 231/270/231 263/303/263 264/304/264
2032
+ f 231/270/231 264/304/264 232/271/232
2033
+ f 232/271/232 264/304/264 265/305/265
2034
+ f 232/271/232 265/305/265 233/272/233
2035
+ f 233/272/233 265/305/265 266/306/266
2036
+ f 233/272/233 266/306/266 234/273/234
2037
+ f 234/273/234 266/306/266 267/307/267
2038
+ f 234/273/234 267/307/267 235/274/235
2039
+ f 235/274/235 267/307/267 268/308/268
2040
+ f 235/274/235 268/308/268 236/275/236
2041
+ f 236/275/236 268/308/268 269/309/269
2042
+ f 236/275/236 269/309/269 237/276/237
2043
+ f 237/276/237 269/309/269 270/310/270
2044
+ f 237/276/237 270/310/270 238/277/238
2045
+ f 238/277/238 270/310/270 271/311/271
2046
+ f 238/277/238 271/311/271 239/278/239
2047
+ f 239/278/239 271/311/271 272/312/272
2048
+ f 239/278/239 272/312/272 240/279/240
2049
+ f 240/279/240 272/312/272 273/313/273
2050
+ f 240/279/240 273/313/273 241/280/241
2051
+ f 241/280/241 273/313/273 274/314/274
2052
+ f 241/280/241 274/314/274 242/281/242
2053
+ f 242/281/242 274/314/274 275/315/275
2054
+ f 242/281/242 275/315/275 243/282/243
2055
+ f 243/282/243 275/315/275 276/316/276
2056
+ f 243/282/243 276/316/276 244/283/244
2057
+ f 244/283/244 276/316/276 277/317/277
2058
+ f 244/283/244 277/317/277 245/284/245
2059
+ f 245/284/245 277/317/277 278/318/278
2060
+ f 245/284/245 278/318/278 246/285/246
2061
+ f 246/285/246 278/318/278 279/319/279
2062
+ f 246/285/246 279/319/279 247/286/247
2063
+ f 247/286/247 279/319/279 280/320/280
2064
+ f 247/286/247 280/320/280 248/287/248
2065
+ f 248/287/248 280/320/280 281/321/281
2066
+ f 248/287/248 281/321/281 249/288/249
2067
+ f 249/288/249 281/321/281 282/322/282
2068
+ f 249/288/249 282/322/282 250/289/250
2069
+ f 250/289/250 282/322/282 283/323/283
2070
+ f 250/289/250 283/323/283 251/290/251
2071
+ f 251/290/251 283/323/283 284/324/284
2072
+ f 251/290/251 284/324/284 252/291/252
2073
+ f 252/291/252 284/324/284 285/325/285
2074
+ f 252/291/252 285/325/285 253/292/253
2075
+ f 253/292/253 285/325/285 286/326/286
2076
+ f 253/292/253 286/326/286 254/293/254
2077
+ f 254/293/254 286/326/286 287/327/287
2078
+ f 254/293/254 287/327/287 255/294/255
2079
+ f 255/294/255 287/327/287 288/328/288
2080
+ f 255/294/255 288/328/288 256/295/256
2081
+ f 256/295/256 288/328/288 289/329/289
2082
+ f 256/295/256 289/329/289 257/296/257
2083
+ f 257/296/257 289/329/289 258/330/258
2084
+ f 257/296/257 258/330/258 226/297/226
2085
+ f 258/298/258 290/331/290 291/332/291
2086
+ f 258/298/258 291/332/291 259/299/259
2087
+ f 259/299/259 291/332/291 292/333/292
2088
+ f 259/299/259 292/333/292 260/300/260
2089
+ f 260/300/260 292/333/292 293/334/293
2090
+ f 260/300/260 293/334/293 261/301/261
2091
+ f 261/301/261 293/334/293 294/335/294
2092
+ f 261/301/261 294/335/294 262/302/262
2093
+ f 262/302/262 294/335/294 295/336/295
2094
+ f 262/302/262 295/336/295 263/303/263
2095
+ f 263/303/263 295/336/295 296/337/296
2096
+ f 263/303/263 296/337/296 264/304/264
2097
+ f 264/304/264 296/337/296 297/338/297
2098
+ f 264/304/264 297/338/297 265/305/265
2099
+ f 265/305/265 297/338/297 298/339/298
2100
+ f 265/305/265 298/339/298 266/306/266
2101
+ f 266/306/266 298/339/298 299/340/299
2102
+ f 266/306/266 299/340/299 267/307/267
2103
+ f 267/307/267 299/340/299 300/341/300
2104
+ f 267/307/267 300/341/300 268/308/268
2105
+ f 268/308/268 300/341/300 301/342/301
2106
+ f 268/308/268 301/342/301 269/309/269
2107
+ f 269/309/269 301/342/301 302/343/302
2108
+ f 269/309/269 302/343/302 270/310/270
2109
+ f 270/310/270 302/343/302 303/344/303
2110
+ f 270/310/270 303/344/303 271/311/271
2111
+ f 271/311/271 303/344/303 304/345/304
2112
+ f 271/311/271 304/345/304 272/312/272
2113
+ f 272/312/272 304/345/304 305/346/305
2114
+ f 272/312/272 305/346/305 273/313/273
2115
+ f 273/313/273 305/346/305 306/347/306
2116
+ f 273/313/273 306/347/306 274/314/274
2117
+ f 274/314/274 306/347/306 307/348/307
2118
+ f 274/314/274 307/348/307 275/315/275
2119
+ f 275/315/275 307/348/307 308/349/308
2120
+ f 275/315/275 308/349/308 276/316/276
2121
+ f 276/316/276 308/349/308 309/350/309
2122
+ f 276/316/276 309/350/309 277/317/277
2123
+ f 277/317/277 309/350/309 310/351/310
2124
+ f 277/317/277 310/351/310 278/318/278
2125
+ f 278/318/278 310/351/310 311/352/311
2126
+ f 278/318/278 311/352/311 279/319/279
2127
+ f 279/319/279 311/352/311 312/353/312
2128
+ f 279/319/279 312/353/312 280/320/280
2129
+ f 280/320/280 312/353/312 313/354/313
2130
+ f 280/320/280 313/354/313 281/321/281
2131
+ f 281/321/281 313/354/313 314/355/314
2132
+ f 281/321/281 314/355/314 282/322/282
2133
+ f 282/322/282 314/355/314 315/356/315
2134
+ f 282/322/282 315/356/315 283/323/283
2135
+ f 283/323/283 315/356/315 316/357/316
2136
+ f 283/323/283 316/357/316 284/324/284
2137
+ f 284/324/284 316/357/316 317/358/317
2138
+ f 284/324/284 317/358/317 285/325/285
2139
+ f 285/325/285 317/358/317 318/359/318
2140
+ f 285/325/285 318/359/318 286/326/286
2141
+ f 286/326/286 318/359/318 319/360/319
2142
+ f 286/326/286 319/360/319 287/327/287
2143
+ f 287/327/287 319/360/319 320/361/320
2144
+ f 287/327/287 320/361/320 288/328/288
2145
+ f 288/328/288 320/361/320 321/362/321
2146
+ f 288/328/288 321/362/321 289/329/289
2147
+ f 289/329/289 321/362/321 290/363/290
2148
+ f 289/329/289 290/363/290 258/330/258
2149
+ f 290/331/290 322/364/322 323/365/323
2150
+ f 290/331/290 323/365/323 291/332/291
2151
+ f 291/332/291 323/365/323 324/366/324
2152
+ f 291/332/291 324/366/324 292/333/292
2153
+ f 292/333/292 324/366/324 325/367/325
2154
+ f 292/333/292 325/367/325 293/334/293
2155
+ f 293/334/293 325/367/325 326/368/326
2156
+ f 293/334/293 326/368/326 294/335/294
2157
+ f 294/335/294 326/368/326 327/369/327
2158
+ f 294/335/294 327/369/327 295/336/295
2159
+ f 295/336/295 327/369/327 328/370/328
2160
+ f 295/336/295 328/370/328 296/337/296
2161
+ f 296/337/296 328/370/328 329/371/329
2162
+ f 296/337/296 329/371/329 297/338/297
2163
+ f 297/338/297 329/371/329 330/372/330
2164
+ f 297/338/297 330/372/330 298/339/298
2165
+ f 298/339/298 330/372/330 331/373/331
2166
+ f 298/339/298 331/373/331 299/340/299
2167
+ f 299/340/299 331/373/331 332/374/332
2168
+ f 299/340/299 332/374/332 300/341/300
2169
+ f 300/341/300 332/374/332 333/375/333
2170
+ f 300/341/300 333/375/333 301/342/301
2171
+ f 301/342/301 333/375/333 334/376/334
2172
+ f 301/342/301 334/376/334 302/343/302
2173
+ f 302/343/302 334/376/334 335/377/335
2174
+ f 302/343/302 335/377/335 303/344/303
2175
+ f 303/344/303 335/377/335 336/378/336
2176
+ f 303/344/303 336/378/336 304/345/304
2177
+ f 304/345/304 336/378/336 337/379/337
2178
+ f 304/345/304 337/379/337 305/346/305
2179
+ f 305/346/305 337/379/337 338/380/338
2180
+ f 305/346/305 338/380/338 306/347/306
2181
+ f 306/347/306 338/380/338 339/381/339
2182
+ f 306/347/306 339/381/339 307/348/307
2183
+ f 307/348/307 339/381/339 340/382/340
2184
+ f 307/348/307 340/382/340 308/349/308
2185
+ f 308/349/308 340/382/340 341/383/341
2186
+ f 308/349/308 341/383/341 309/350/309
2187
+ f 309/350/309 341/383/341 342/384/342
2188
+ f 309/350/309 342/384/342 310/351/310
2189
+ f 310/351/310 342/384/342 343/385/343
2190
+ f 310/351/310 343/385/343 311/352/311
2191
+ f 311/352/311 343/385/343 344/386/344
2192
+ f 311/352/311 344/386/344 312/353/312
2193
+ f 312/353/312 344/386/344 345/387/345
2194
+ f 312/353/312 345/387/345 313/354/313
2195
+ f 313/354/313 345/387/345 346/388/346
2196
+ f 313/354/313 346/388/346 314/355/314
2197
+ f 314/355/314 346/388/346 347/389/347
2198
+ f 314/355/314 347/389/347 315/356/315
2199
+ f 315/356/315 347/389/347 348/390/348
2200
+ f 315/356/315 348/390/348 316/357/316
2201
+ f 316/357/316 348/390/348 349/391/349
2202
+ f 316/357/316 349/391/349 317/358/317
2203
+ f 317/358/317 349/391/349 350/392/350
2204
+ f 317/358/317 350/392/350 318/359/318
2205
+ f 318/359/318 350/392/350 351/393/351
2206
+ f 318/359/318 351/393/351 319/360/319
2207
+ f 319/360/319 351/393/351 352/394/352
2208
+ f 319/360/319 352/394/352 320/361/320
2209
+ f 320/361/320 352/394/352 353/395/353
2210
+ f 320/361/320 353/395/353 321/362/321
2211
+ f 321/362/321 353/395/353 322/396/322
2212
+ f 321/362/321 322/396/322 290/363/290
2213
+ f 322/364/322 354/397/354 355/398/355
2214
+ f 322/364/322 355/398/355 323/365/323
2215
+ f 323/365/323 355/398/355 356/399/356
2216
+ f 323/365/323 356/399/356 324/366/324
2217
+ f 324/366/324 356/399/356 357/400/357
2218
+ f 324/366/324 357/400/357 325/367/325
2219
+ f 325/367/325 357/400/357 358/401/358
2220
+ f 325/367/325 358/401/358 326/368/326
2221
+ f 326/368/326 358/401/358 359/402/359
2222
+ f 326/368/326 359/402/359 327/369/327
2223
+ f 327/369/327 359/402/359 360/403/360
2224
+ f 327/369/327 360/403/360 328/370/328
2225
+ f 328/370/328 360/403/360 361/404/361
2226
+ f 328/370/328 361/404/361 329/371/329
2227
+ f 329/371/329 361/404/361 362/405/362
2228
+ f 329/371/329 362/405/362 330/372/330
2229
+ f 330/372/330 362/405/362 363/406/363
2230
+ f 330/372/330 363/406/363 331/373/331
2231
+ f 331/373/331 363/406/363 364/407/364
2232
+ f 331/373/331 364/407/364 332/374/332
2233
+ f 332/374/332 364/407/364 365/408/365
2234
+ f 332/374/332 365/408/365 333/375/333
2235
+ f 333/375/333 365/408/365 366/409/366
2236
+ f 333/375/333 366/409/366 334/376/334
2237
+ f 334/376/334 366/409/366 367/410/367
2238
+ f 334/376/334 367/410/367 335/377/335
2239
+ f 335/377/335 367/410/367 368/411/368
2240
+ f 335/377/335 368/411/368 336/378/336
2241
+ f 336/378/336 368/411/368 369/412/369
2242
+ f 336/378/336 369/412/369 337/379/337
2243
+ f 337/379/337 369/412/369 370/413/370
2244
+ f 337/379/337 370/413/370 338/380/338
2245
+ f 338/380/338 370/413/370 371/414/371
2246
+ f 338/380/338 371/414/371 339/381/339
2247
+ f 339/381/339 371/414/371 372/415/372
2248
+ f 339/381/339 372/415/372 340/382/340
2249
+ f 340/382/340 372/415/372 373/416/373
2250
+ f 340/382/340 373/416/373 341/383/341
2251
+ f 341/383/341 373/416/373 374/417/374
2252
+ f 341/383/341 374/417/374 342/384/342
2253
+ f 342/384/342 374/417/374 375/418/375
2254
+ f 342/384/342 375/418/375 343/385/343
2255
+ f 343/385/343 375/418/375 376/419/376
2256
+ f 343/385/343 376/419/376 344/386/344
2257
+ f 344/386/344 376/419/376 377/420/377
2258
+ f 344/386/344 377/420/377 345/387/345
2259
+ f 345/387/345 377/420/377 378/421/378
2260
+ f 345/387/345 378/421/378 346/388/346
2261
+ f 346/388/346 378/421/378 379/422/379
2262
+ f 346/388/346 379/422/379 347/389/347
2263
+ f 347/389/347 379/422/379 380/423/380
2264
+ f 347/389/347 380/423/380 348/390/348
2265
+ f 348/390/348 380/423/380 381/424/381
2266
+ f 348/390/348 381/424/381 349/391/349
2267
+ f 349/391/349 381/424/381 382/425/382
2268
+ f 349/391/349 382/425/382 350/392/350
2269
+ f 350/392/350 382/425/382 383/426/383
2270
+ f 350/392/350 383/426/383 351/393/351
2271
+ f 351/393/351 383/426/383 384/427/384
2272
+ f 351/393/351 384/427/384 352/394/352
2273
+ f 352/394/352 384/427/384 385/428/385
2274
+ f 352/394/352 385/428/385 353/395/353
2275
+ f 353/395/353 385/428/385 354/429/354
2276
+ f 353/395/353 354/429/354 322/396/322
2277
+ f 354/397/354 386/430/386 387/431/387
2278
+ f 354/397/354 387/431/387 355/398/355
2279
+ f 355/398/355 387/431/387 388/432/388
2280
+ f 355/398/355 388/432/388 356/399/356
2281
+ f 356/399/356 388/432/388 389/433/389
2282
+ f 356/399/356 389/433/389 357/400/357
2283
+ f 357/400/357 389/433/389 390/434/390
2284
+ f 357/400/357 390/434/390 358/401/358
2285
+ f 358/401/358 390/434/390 391/435/391
2286
+ f 358/401/358 391/435/391 359/402/359
2287
+ f 359/402/359 391/435/391 392/436/392
2288
+ f 359/402/359 392/436/392 360/403/360
2289
+ f 360/403/360 392/436/392 393/437/393
2290
+ f 360/403/360 393/437/393 361/404/361
2291
+ f 361/404/361 393/437/393 394/438/394
2292
+ f 361/404/361 394/438/394 362/405/362
2293
+ f 362/405/362 394/438/394 395/439/395
2294
+ f 362/405/362 395/439/395 363/406/363
2295
+ f 363/406/363 395/439/395 396/440/396
2296
+ f 363/406/363 396/440/396 364/407/364
2297
+ f 364/407/364 396/440/396 397/441/397
2298
+ f 364/407/364 397/441/397 365/408/365
2299
+ f 365/408/365 397/441/397 398/442/398
2300
+ f 365/408/365 398/442/398 366/409/366
2301
+ f 366/409/366 398/442/398 399/443/399
2302
+ f 366/409/366 399/443/399 367/410/367
2303
+ f 367/410/367 399/443/399 400/444/400
2304
+ f 367/410/367 400/444/400 368/411/368
2305
+ f 368/411/368 400/444/400 401/445/401
2306
+ f 368/411/368 401/445/401 369/412/369
2307
+ f 369/412/369 401/445/401 402/446/402
2308
+ f 369/412/369 402/446/402 370/413/370
2309
+ f 370/413/370 402/446/402 403/447/403
2310
+ f 370/413/370 403/447/403 371/414/371
2311
+ f 371/414/371 403/447/403 404/448/404
2312
+ f 371/414/371 404/448/404 372/415/372
2313
+ f 372/415/372 404/448/404 405/449/405
2314
+ f 372/415/372 405/449/405 373/416/373
2315
+ f 373/416/373 405/449/405 406/450/406
2316
+ f 373/416/373 406/450/406 374/417/374
2317
+ f 374/417/374 406/450/406 407/451/407
2318
+ f 374/417/374 407/451/407 375/418/375
2319
+ f 375/418/375 407/451/407 408/452/408
2320
+ f 375/418/375 408/452/408 376/419/376
2321
+ f 376/419/376 408/452/408 409/453/409
2322
+ f 376/419/376 409/453/409 377/420/377
2323
+ f 377/420/377 409/453/409 410/454/410
2324
+ f 377/420/377 410/454/410 378/421/378
2325
+ f 378/421/378 410/454/410 411/455/411
2326
+ f 378/421/378 411/455/411 379/422/379
2327
+ f 379/422/379 411/455/411 412/456/412
2328
+ f 379/422/379 412/456/412 380/423/380
2329
+ f 380/423/380 412/456/412 413/457/413
2330
+ f 380/423/380 413/457/413 381/424/381
2331
+ f 381/424/381 413/457/413 414/458/414
2332
+ f 381/424/381 414/458/414 382/425/382
2333
+ f 382/425/382 414/458/414 415/459/415
2334
+ f 382/425/382 415/459/415 383/426/383
2335
+ f 383/426/383 415/459/415 416/460/416
2336
+ f 383/426/383 416/460/416 384/427/384
2337
+ f 384/427/384 416/460/416 417/461/417
2338
+ f 384/427/384 417/461/417 385/428/385
2339
+ f 385/428/385 417/461/417 386/462/386
2340
+ f 385/428/385 386/462/386 354/429/354
2341
+ f 386/430/386 418/463/418 419/464/419
2342
+ f 386/430/386 419/464/419 387/431/387
2343
+ f 387/431/387 419/464/419 420/465/420
2344
+ f 387/431/387 420/465/420 388/432/388
2345
+ f 388/432/388 420/465/420 421/466/421
2346
+ f 388/432/388 421/466/421 389/433/389
2347
+ f 389/433/389 421/466/421 422/467/422
2348
+ f 389/433/389 422/467/422 390/434/390
2349
+ f 390/434/390 422/467/422 423/468/423
2350
+ f 390/434/390 423/468/423 391/435/391
2351
+ f 391/435/391 423/468/423 424/469/424
2352
+ f 391/435/391 424/469/424 392/436/392
2353
+ f 392/436/392 424/469/424 425/470/425
2354
+ f 392/436/392 425/470/425 393/437/393
2355
+ f 393/437/393 425/470/425 426/471/426
2356
+ f 393/437/393 426/471/426 394/438/394
2357
+ f 394/438/394 426/471/426 427/472/427
2358
+ f 394/438/394 427/472/427 395/439/395
2359
+ f 395/439/395 427/472/427 428/473/428
2360
+ f 395/439/395 428/473/428 396/440/396
2361
+ f 396/440/396 428/473/428 429/474/429
2362
+ f 396/440/396 429/474/429 397/441/397
2363
+ f 397/441/397 429/474/429 430/475/430
2364
+ f 397/441/397 430/475/430 398/442/398
2365
+ f 398/442/398 430/475/430 431/476/431
2366
+ f 398/442/398 431/476/431 399/443/399
2367
+ f 399/443/399 431/476/431 432/477/432
2368
+ f 399/443/399 432/477/432 400/444/400
2369
+ f 400/444/400 432/477/432 433/478/433
2370
+ f 400/444/400 433/478/433 401/445/401
2371
+ f 401/445/401 433/478/433 434/479/434
2372
+ f 401/445/401 434/479/434 402/446/402
2373
+ f 402/446/402 434/479/434 435/480/435
2374
+ f 402/446/402 435/480/435 403/447/403
2375
+ f 403/447/403 435/480/435 436/481/436
2376
+ f 403/447/403 436/481/436 404/448/404
2377
+ f 404/448/404 436/481/436 437/482/437
2378
+ f 404/448/404 437/482/437 405/449/405
2379
+ f 405/449/405 437/482/437 438/483/438
2380
+ f 405/449/405 438/483/438 406/450/406
2381
+ f 406/450/406 438/483/438 439/484/439
2382
+ f 406/450/406 439/484/439 407/451/407
2383
+ f 407/451/407 439/484/439 440/485/440
2384
+ f 407/451/407 440/485/440 408/452/408
2385
+ f 408/452/408 440/485/440 441/486/441
2386
+ f 408/452/408 441/486/441 409/453/409
2387
+ f 409/453/409 441/486/441 442/487/442
2388
+ f 409/453/409 442/487/442 410/454/410
2389
+ f 410/454/410 442/487/442 443/488/443
2390
+ f 410/454/410 443/488/443 411/455/411
2391
+ f 411/455/411 443/488/443 444/489/444
2392
+ f 411/455/411 444/489/444 412/456/412
2393
+ f 412/456/412 444/489/444 445/490/445
2394
+ f 412/456/412 445/490/445 413/457/413
2395
+ f 413/457/413 445/490/445 446/491/446
2396
+ f 413/457/413 446/491/446 414/458/414
2397
+ f 414/458/414 446/491/446 447/492/447
2398
+ f 414/458/414 447/492/447 415/459/415
2399
+ f 415/459/415 447/492/447 448/493/448
2400
+ f 415/459/415 448/493/448 416/460/416
2401
+ f 416/460/416 448/493/448 449/494/449
2402
+ f 416/460/416 449/494/449 417/461/417
2403
+ f 417/461/417 449/494/449 418/495/418
2404
+ f 417/461/417 418/495/418 386/462/386
2405
+ f 418/463/418 450/496/450 451/497/451
2406
+ f 418/463/418 451/497/451 419/464/419
2407
+ f 419/464/419 451/497/451 452/498/452
2408
+ f 419/464/419 452/498/452 420/465/420
2409
+ f 420/465/420 452/498/452 453/499/453
2410
+ f 420/465/420 453/499/453 421/466/421
2411
+ f 421/466/421 453/499/453 454/500/454
2412
+ f 421/466/421 454/500/454 422/467/422
2413
+ f 422/467/422 454/500/454 455/501/455
2414
+ f 422/467/422 455/501/455 423/468/423
2415
+ f 423/468/423 455/501/455 456/502/456
2416
+ f 423/468/423 456/502/456 424/469/424
2417
+ f 424/469/424 456/502/456 457/503/457
2418
+ f 424/469/424 457/503/457 425/470/425
2419
+ f 425/470/425 457/503/457 458/504/458
2420
+ f 425/470/425 458/504/458 426/471/426
2421
+ f 426/471/426 458/504/458 459/505/459
2422
+ f 426/471/426 459/505/459 427/472/427
2423
+ f 427/472/427 459/505/459 460/506/460
2424
+ f 427/472/427 460/506/460 428/473/428
2425
+ f 428/473/428 460/506/460 461/507/461
2426
+ f 428/473/428 461/507/461 429/474/429
2427
+ f 429/474/429 461/507/461 462/508/462
2428
+ f 429/474/429 462/508/462 430/475/430
2429
+ f 430/475/430 462/508/462 463/509/463
2430
+ f 430/475/430 463/509/463 431/476/431
2431
+ f 431/476/431 463/509/463 464/510/464
2432
+ f 431/476/431 464/510/464 432/477/432
2433
+ f 432/477/432 464/510/464 465/511/465
2434
+ f 432/477/432 465/511/465 433/478/433
2435
+ f 433/478/433 465/511/465 466/512/466
2436
+ f 433/478/433 466/512/466 434/479/434
2437
+ f 434/479/434 466/512/466 467/513/467
2438
+ f 434/479/434 467/513/467 435/480/435
2439
+ f 435/480/435 467/513/467 468/514/468
2440
+ f 435/480/435 468/514/468 436/481/436
2441
+ f 436/481/436 468/514/468 469/515/469
2442
+ f 436/481/436 469/515/469 437/482/437
2443
+ f 437/482/437 469/515/469 470/516/470
2444
+ f 437/482/437 470/516/470 438/483/438
2445
+ f 438/483/438 470/516/470 471/517/471
2446
+ f 438/483/438 471/517/471 439/484/439
2447
+ f 439/484/439 471/517/471 472/518/472
2448
+ f 439/484/439 472/518/472 440/485/440
2449
+ f 440/485/440 472/518/472 473/519/473
2450
+ f 440/485/440 473/519/473 441/486/441
2451
+ f 441/486/441 473/519/473 474/520/474
2452
+ f 441/486/441 474/520/474 442/487/442
2453
+ f 442/487/442 474/520/474 475/521/475
2454
+ f 442/487/442 475/521/475 443/488/443
2455
+ f 443/488/443 475/521/475 476/522/476
2456
+ f 443/488/443 476/522/476 444/489/444
2457
+ f 444/489/444 476/522/476 477/523/477
2458
+ f 444/489/444 477/523/477 445/490/445
2459
+ f 445/490/445 477/523/477 478/524/478
2460
+ f 445/490/445 478/524/478 446/491/446
2461
+ f 446/491/446 478/524/478 479/525/479
2462
+ f 446/491/446 479/525/479 447/492/447
2463
+ f 447/492/447 479/525/479 480/526/480
2464
+ f 447/492/447 480/526/480 448/493/448
2465
+ f 448/493/448 480/526/480 481/527/481
2466
+ f 448/493/448 481/527/481 449/494/449
2467
+ f 449/494/449 481/527/481 450/528/450
2468
+ f 449/494/449 450/528/450 418/495/418
2469
+ f 482/529/482 451/497/451 450/496/450
2470
+ f 482/530/482 452/498/452 451/497/451
2471
+ f 482/531/482 453/499/453 452/498/452
2472
+ f 482/532/482 454/500/454 453/499/453
2473
+ f 482/533/482 455/501/455 454/500/454
2474
+ f 482/534/482 456/502/456 455/501/455
2475
+ f 482/535/482 457/503/457 456/502/456
2476
+ f 482/536/482 458/504/458 457/503/457
2477
+ f 482/537/482 459/505/459 458/504/458
2478
+ f 482/538/482 460/506/460 459/505/459
2479
+ f 482/539/482 461/507/461 460/506/460
2480
+ f 482/540/482 462/508/462 461/507/461
2481
+ f 482/541/482 463/509/463 462/508/462
2482
+ f 482/542/482 464/510/464 463/509/463
2483
+ f 482/543/482 465/511/465 464/510/464
2484
+ f 482/544/482 466/512/466 465/511/465
2485
+ f 482/545/482 467/513/467 466/512/466
2486
+ f 482/546/482 468/514/468 467/513/467
2487
+ f 482/547/482 469/515/469 468/514/468
2488
+ f 482/548/482 470/516/470 469/515/469
2489
+ f 482/549/482 471/517/471 470/516/470
2490
+ f 482/550/482 472/518/472 471/517/471
2491
+ f 482/551/482 473/519/473 472/518/472
2492
+ f 482/552/482 474/520/474 473/519/473
2493
+ f 482/553/482 475/521/475 474/520/474
2494
+ f 482/554/482 476/522/476 475/521/475
2495
+ f 482/555/482 477/523/477 476/522/476
2496
+ f 482/556/482 478/524/478 477/523/477
2497
+ f 482/557/482 479/525/479 478/524/478
2498
+ f 482/558/482 480/526/480 479/525/479
2499
+ f 482/559/482 481/527/481 480/526/480
2500
+ f 482/560/482 450/528/450 481/527/481
2501
+ # 960 faces
2502
+
2503
+ g
third_party/ktx-src/tests/loadtests/common/models/teapot.dae ADDED
The diff for this file is too large to render. See raw diff
 
third_party/ktx-src/tests/loadtests/common/models/torusknot.obj ADDED
The diff for this file is too large to render. See raw diff
 
third_party/ktx-src/tests/loadtests/common/reenable_warnings.h ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* -*- tab-width: 4; -*- */
2
+ /* vi: set sw=2 ts=4 expandtab: */
3
+
4
+ /*
5
+ * Copyright 2021 Mark Callow.
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+
9
+ #if !defined REENABLE_WARNINGS_H
10
+
11
+ // Reenable warnings disabled by, e.g. disable_glm_warnings.h.
12
+ #if defined(_MSC_VER)
13
+ #pragma warning(pop)
14
+ #elif defined(__clang__)
15
+ #pragma clang diagnostic pop
16
+ #endif
17
+
18
+ #endif /* REENABLE_WARNINGS_H */
third_party/ktx-src/tests/loadtests/common/vecmath.hpp ADDED
@@ -0,0 +1,448 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* -*- tab-width: 4; -*- */
2
+ /* vi: set sw=2 ts=4 expandtab: */
3
+
4
+ /*
5
+ * Copyright 2016-2020 Mark Callow
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+
9
+ #ifndef VECMATH_9B7E1CFE346D11E6AFA2D7DC87495A69_H
10
+ #define VECMATH_9B7E1CFE346D11E6AFA2D7DC87495A69_H
11
+
12
+ /**
13
+ * @file
14
+ * @~English
15
+ *
16
+ * @brief Vector math package modelled after GLSL.
17
+ */
18
+
19
+ #include <assert.h>
20
+ #include <math.h>
21
+
22
+ struct vec2 {
23
+ // Anonymous unions are portable.
24
+ union {
25
+ float x;
26
+ float r;
27
+ };
28
+ union {
29
+ float y;
30
+ float g;
31
+ };
32
+
33
+ vec2() { };
34
+ };
35
+
36
+ struct vec3 {
37
+ union {
38
+ float x;
39
+ float r;
40
+ };
41
+ union {
42
+ float y;
43
+ float g;
44
+ };
45
+ union {
46
+ float z;
47
+ float b;
48
+ };
49
+
50
+ vec3() { }
51
+
52
+ vec3(float x, float y, float z) : x(x), y(y), z(z) { }
53
+
54
+ vec3(const vec3& value)
55
+ : x(value.x), y(value.y), z(value.z) { }
56
+
57
+ vec3 operator-() const
58
+ {
59
+ return vec3(-x, -y, -z);
60
+ }
61
+
62
+ vec3 operator-(const vec3& value) const
63
+ {
64
+ return vec3(this->x - value.x, this->y - value.y, this->z - value.z);
65
+ }
66
+
67
+ vec3 operator/(float divisor) const
68
+ {
69
+ return vec3(x / divisor, y / divisor, z / divisor);
70
+ }
71
+
72
+ vec3& operator/=(float divisor)
73
+ {
74
+ x /= divisor;
75
+ y /= divisor;
76
+ z /= divisor;
77
+ return *this;
78
+ }
79
+
80
+ vec3& operator=(const vec3& value)
81
+ {
82
+ x = value.x;
83
+ y = value.y;
84
+ z = value.z;
85
+ return *this;
86
+ }
87
+
88
+ float operator[](int i) const
89
+ {
90
+ switch (i) {
91
+ case 0: return x;
92
+ case 1: return y;
93
+ case 2: return z;
94
+ default:
95
+ assert(false);
96
+ return z;
97
+ }
98
+ }
99
+
100
+ float& operator[](int i)
101
+ {
102
+ switch (i) {
103
+ case 0: return x;
104
+ case 1: return y;
105
+ case 2: return z;
106
+ default:
107
+ assert(false);
108
+ return z;
109
+ }
110
+ }
111
+
112
+ vec3 cross(const vec3& value) const
113
+ {
114
+ return vec3::cross(*this, value);
115
+ }
116
+
117
+ float dot(const vec3& vec) const
118
+ {
119
+ return vec3::dot(*this, vec);
120
+ }
121
+
122
+ float length() const
123
+ {
124
+ return sqrt(dot(*this));
125
+ }
126
+
127
+ vec3& normalize()
128
+ {
129
+ float length = this->length();
130
+ return (length > 0.0f ? *this /= length : *this);
131
+ }
132
+
133
+ static vec3 cross(const vec3& a, const vec3& b)
134
+ {
135
+ return vec3(a.y * b.z - a.z * b.y,
136
+ a.z * b.x - a.x * b.z,
137
+ a.x * b.y - a.y * b.x);
138
+ }
139
+
140
+ static float dot(const vec3& a, const vec3& b)
141
+ {
142
+ return a.x * b.x + a.y * b.y + a.z * b.z;
143
+ }
144
+
145
+ static vec3 normalize (const vec3& input)
146
+ {
147
+ float length = input.length();
148
+ return (length > 0.0f ? input / length : input);
149
+ }
150
+ };
151
+
152
+
153
+ struct vec4 {
154
+
155
+ union {
156
+ float x;
157
+ float r;
158
+ };
159
+ union {
160
+ float y;
161
+ float g;
162
+ };
163
+ union {
164
+ float z;
165
+ float b;
166
+ };
167
+ union {
168
+ float w;
169
+ float a;
170
+ };
171
+
172
+ vec4() { }
173
+
174
+ vec4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) { }
175
+
176
+ vec4(const vec3& value, float w)
177
+ : x(value.x), y(value.y), z(value.z), w(w) { }
178
+
179
+ vec4(const vec4& value)
180
+ : x(value.x), y(value.y), z(value.z), w(value.w) { }
181
+
182
+ vec4 operator/(float divisor) const
183
+ {
184
+ return vec4(x / divisor, y / divisor, z / divisor, w / divisor);
185
+ }
186
+
187
+ vec4& operator/=(float divisor)
188
+ {
189
+ x /= divisor;
190
+ y /= divisor;
191
+ z /= divisor;
192
+ w /= divisor;
193
+ return *this;
194
+ }
195
+
196
+ vec4 operator*(float multiplicand) const
197
+ {
198
+ return vec4(x * multiplicand, y * multiplicand, z * multiplicand,
199
+ w * multiplicand);
200
+ }
201
+
202
+ vec4& operator=(const vec4& value)
203
+ {
204
+ x = value.x;
205
+ y = value.y;
206
+ z = value.z;
207
+ w = value.w;
208
+ return *this;
209
+ }
210
+
211
+ float operator[](int i) const
212
+ {
213
+ switch (i) {
214
+ case 0: return x;
215
+ case 1: return y;
216
+ case 2: return z;
217
+ case 3: return w;
218
+ default:
219
+ assert(false);
220
+ return z;
221
+ }
222
+ }
223
+
224
+ float& operator[](int i)
225
+ {
226
+ switch (i) {
227
+ case 0: return x;
228
+ case 1: return y;
229
+ case 2: return z;
230
+ case 3: return w;
231
+ default:
232
+ assert(false);
233
+ return z;
234
+ }
235
+ }
236
+
237
+ float dot(const vec4& vec) const
238
+ {
239
+ return vec4::dot(*this, vec);
240
+ }
241
+
242
+ float length() const
243
+ {
244
+ return sqrt(dot(*this));
245
+ }
246
+
247
+ static float dot(const vec4& a, const vec4& b)
248
+ {
249
+ return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
250
+ }
251
+
252
+ static vec4 normalize (const vec4& input)
253
+ {
254
+ float length = input.length();
255
+ return (length > 0.0f ? input / length : input);
256
+ }
257
+ };
258
+
259
+ struct mat3 {
260
+ vec3 m[3];
261
+
262
+ mat3()
263
+ {
264
+ m[0] = vec3(1.0f, 0.0f, 0.0f);
265
+ m[1] = vec3(0.0f, 1.0f, 0.0f);
266
+ m[2] = vec3(0.0f, 0.0f, 1.0f);
267
+ }
268
+
269
+ mat3(const vec3& value1, const vec3& value2, const vec3& value3)
270
+ {
271
+ m[0] = value1;
272
+ m[1] = value2;
273
+ m[2] = value3;
274
+ }
275
+
276
+ mat3 transpose() const
277
+ {
278
+ return mat3(vec3(m[0].x, m[1].x, m[2].x),
279
+ vec3(m[0].y, m[1].y, m[2].y),
280
+ vec3(m[0].z, m[1].z, m[2].z));
281
+ }
282
+ };
283
+
284
+ struct mat4 {
285
+ vec4 m[4];
286
+
287
+ mat4()
288
+ {
289
+ m[0] = vec4(1.0f, 0.0f, 0.0f, 0.0f);
290
+ m[1] = vec4(0.0f, 1.0f, 0.0f, 0.0f);
291
+ m[2] = vec4(0.0f, 0.0f, 1.0f, 0.0f);
292
+ m[3] = vec4(0.0f, 0.0f, 0.0f, 1.0f);
293
+ }
294
+
295
+ mat4(const vec4& value1, const vec4& value2,
296
+ const vec4& value3, const vec4& value4)
297
+ {
298
+ m[0] = value1;
299
+ m[1] = value2;
300
+ m[2] = value3;
301
+ m[3] = value4;
302
+ }
303
+
304
+ mat4 operator*(float value) const
305
+ {
306
+ return mat4(m[0] * value, m[1] * value, m[2] * value, m[3] * value);
307
+ }
308
+
309
+ mat4 operator*(const mat4& value) const
310
+ {
311
+ mat4 right = value.transpose();
312
+ return mat4(
313
+ vec4(m[0].dot(right.m[0]), m[0].dot(right.m[1]),
314
+ m[0].dot(right.m[2]), m[0].dot(right.m[3])),
315
+ vec4(m[1].dot(right.m[0]), m[1].dot(right.m[1]),
316
+ m[1].dot(right.m[2]), m[1].dot(right.m[3])),
317
+ vec4(m[2].dot(right.m[0]), m[2].dot(right.m[1]),
318
+ m[2].dot(right.m[2]), m[2].dot(right.m[3])),
319
+ vec4(m[3].dot(right.m[0]), m[3].dot(right.m[1]),
320
+ m[3].dot(right.m[2]), m[3].dot(right.m[3]))
321
+ );
322
+ }
323
+
324
+ vec4 operator*(const vec4& value) const
325
+ {
326
+ return vec4(m[0].dot(value), m[1].dot(value),
327
+ m[2].dot(value), m[3].dot(value));
328
+ }
329
+
330
+ vec4& operator[](int i)
331
+ {
332
+ return m[i];
333
+ }
334
+
335
+ mat4 transpose() const
336
+ {
337
+ return mat4(vec4(m[0][0], m[1][0], m[2][0], m[3][0]),
338
+ vec4(m[0][1], m[1][1], m[2][1], m[3][1]),
339
+ vec4(m[0][2], m[1][2], m[2][2], m[3][2]),
340
+ vec4(m[0][3], m[1][3], m[2][3], m[3][3]));
341
+ }
342
+
343
+ static mat4 translate(const vec3& trans)
344
+ {
345
+ return mat4(vec4(1.0f, 0.0f, 0.0f, trans.x),
346
+ vec4(0.0f, 1.0f, 0.0f, trans.y),
347
+ vec4(0.0f, 0.0f, 1.0f, trans.z),
348
+ vec4(0.0f, 0.0f, 0.0f, 1.0f));
349
+ }
350
+
351
+ static mat4 translate(float x, float y, float z)
352
+ {
353
+ return mat4(vec4(1.0f, 0.0f, 0.0f, x),
354
+ vec4(0.0f, 1.0f, 0.0f, y),
355
+ vec4(0.0f, 0.0f, 1.0f, z),
356
+ vec4(0.0f, 0.0f, 0.0f, 1.0f));
357
+ }
358
+
359
+ static mat4 scale(const vec3& scale)
360
+ {
361
+ return mat4(vec4(scale.x, 0.0f, 0.0f, 0.0f),
362
+ vec4(0.0f, scale.y, 0.0f, 0.0f),
363
+ vec4(0.0f, 0.0f, scale.z, 0.0f),
364
+ vec4(0.0f, 0.0f, 0.0f, 1.0f));
365
+ }
366
+
367
+ static mat4 scale(float x, float y, float z)
368
+ {
369
+ return mat4(vec4(x, 0.0f, 0.0f, 0.0f),
370
+ vec4(0.0f, y, 0.0f, 0.0f),
371
+ vec4(0.0f, 0.0f, z, 0.0f),
372
+ vec4(0.0f, 0.0f, 0.0f, 1.0f));
373
+ }
374
+
375
+ static mat4 frustum(float left, float right, float bottom, float top,
376
+ float zNear, float zFar)
377
+ {
378
+ return mat4(
379
+ vec4(2.0f * zNear / (right - left), 0.0f,
380
+ (right + left) / (right - left), 0.0f),
381
+ vec4(0.0f, 2.0f * zNear / (top - bottom),
382
+ (top + bottom) / (top - bottom), 0.0f),
383
+ vec4(0.0f, 0.0f, (zFar + zNear) / (zNear - zFar),
384
+ 2.0f * zFar * zNear / (zNear - zFar)),
385
+ vec4(0.0f, 0.0f, -1.0f, 0.0f)
386
+ );
387
+ }
388
+
389
+ static mat4 ortho(float left, float right, float bottom, float top,
390
+ float zNear, float zFar)
391
+ {
392
+ return mat4(
393
+ vec4(2.0f / (right - left), 0.0f, 0.0f,
394
+ (right + left) / (left - right)),
395
+ vec4(0.0f, 2.0f / (top - bottom), 0.0f,
396
+ (top + bottom) / (bottom - top)),
397
+ vec4(0.0f, 0.0f, 2.0f / (zNear - zFar),
398
+ (zFar + zNear) / (zNear - zFar)),
399
+ vec4(0.0f, 0.0f, 0.0f, 1.0f)
400
+ );
401
+ }
402
+
403
+ static mat4 lookAt(const vec3& eye, const vec3& center, const vec3& up)
404
+ {
405
+ vec3 const forward(vec3::normalize(center - eye));
406
+ vec3 const side(vec3::normalize(vec3::cross(forward, up)));
407
+ vec3 const u(vec3::cross(side, forward));
408
+
409
+ mat4 result;
410
+ result[0][0] = side.x;
411
+ result[1][0] = side.y;
412
+ result[2][0] = side.z;
413
+ result[0][1] = u.x;
414
+ result[1][1] = u.y;
415
+ result[2][1] = u.z;
416
+ result[0][2] =-forward.x;
417
+ result[1][2] =-forward.y;
418
+ result[2][2] =-forward.z;
419
+ result[3][0] =-vec3::dot(side, eye);
420
+ result[3][1] =-vec3::dot(u, eye);
421
+ result[3][2] = vec3::dot(forward, eye);
422
+
423
+ return result;
424
+ }
425
+
426
+ static mat4 lookAt(float eyeX, float eyeY, float eyeZ,
427
+ float centerX, float centerY, float centerZ,
428
+ float upX, float upY, float upZ)
429
+ {
430
+ return mat4::lookAt(vec3(eyeX, eyeY, eyeZ),
431
+ vec3(centerX, centerY, centerZ),
432
+ vec3(upX, upY, upZ));
433
+ }
434
+
435
+ static mat4 perspective(float fovY, float aspect, float zNear, float zFar)
436
+ {
437
+ float scaleY = 1.0f / tan(fovY * 3.1415962f / 360.0f);
438
+ return mat4(
439
+ vec4(scaleY / aspect, 0.0f, 0.0f, 0.0f),
440
+ vec4(0.0f, scaleY, 0.0f, 0.0f),
441
+ vec4(0.0f, 0.0f, (zFar + zNear) / (zNear - zFar),
442
+ (2.0f * zFar * zNear) / (zNear - zFar)),
443
+ vec4(0.0f, 0.0f, -1.0f, 0.0f)
444
+ );
445
+ }
446
+ };
447
+
448
+ #endif /* VECMATH_9B7E1CFE-346D-11E6-AFA2-D7DC87495A69_H */
third_party/ktx-src/tests/loadtests/compile_shader.cmake ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2020 Andreas Atteneder
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ function(compile_shader shader_target shader_name shader_src_path shader_path)
5
+
6
+ set(vert_name "${shader_name}.vert")
7
+ set(vert2spirv_in "${shader_src_path}/${vert_name}")
8
+ set(vert2spirv_out "${CMAKE_CURRENT_BINARY_DIR}/${shader_path}/${vert_name}.spv")
9
+
10
+ add_custom_command(OUTPUT
11
+ ${vert2spirv_out}
12
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/${shader_path}
13
+ COMMAND glslc "-fshader-stage=vertex" -o "${vert2spirv_out}" "${vert2spirv_in}"
14
+ DEPENDS ${vert2spirv_in}
15
+ WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
16
+ COMMENT "Compiling ${vert_name}."
17
+ VERBATIM
18
+ )
19
+
20
+ set(frag_name "${shader_name}.frag")
21
+ set(frag2spirv_in "${shader_src_path}/${frag_name}")
22
+ set(frag2spirv_out "${CMAKE_CURRENT_BINARY_DIR}/${shader_path}/${frag_name}.spv")
23
+
24
+ add_custom_command(OUTPUT
25
+ ${frag2spirv_out}
26
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/${shader_path}
27
+ COMMAND glslc "-fshader-stage=fragment" -o "${frag2spirv_out}" "${frag2spirv_in}"
28
+ DEPENDS ${frag2spirv_in}
29
+ WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
30
+ COMMENT "Compiling ${frag_name}."
31
+ VERBATIM
32
+ )
33
+
34
+ add_custom_target(
35
+ ${shader_target}
36
+ DEPENDS
37
+ ${vert2spirv_out}
38
+ ${frag2spirv_out}
39
+ SOURCES
40
+ ${vert2spirv_in}
41
+ ${frag2spirv_in}
42
+ )
43
+
44
+ set_target_properties(${shader_target} PROPERTIES EXCLUDE_FROM_ALL "FALSE")
45
+
46
+ set(SHADER_SOURCES ${SHADER_SOURCES} ${frag2spirv_out} ${vert2spirv_out} PARENT_SCOPE)
47
+
48
+ endfunction(compile_shader)
49
+
50
+ function(compile_shader_list shader_target shader_src_path shader_path)
51
+
52
+ foreach(shader ${ARGN})
53
+ set(spirv_in "${shader_src_path}/${shader}")
54
+ set(spirv_out "${CMAKE_CURRENT_BINARY_DIR}/${shader_path}/${shader}.spv")
55
+
56
+ add_custom_command(OUTPUT
57
+ ${spirv_out}
58
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/${shader_path}
59
+ COMMAND glslc -o "${spirv_out}" "${spirv_in}"
60
+ DEPENDS ${spirv_in}
61
+ WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
62
+ COMMENT "Compiling ${shader}."
63
+ VERBATIM
64
+ )
65
+
66
+ list(APPEND inputs ${spirv_in})
67
+ list(APPEND outputs ${spirv_out})
68
+ endforeach()
69
+
70
+ add_custom_target(
71
+ ${shader_target}
72
+ DEPENDS ${outputs}
73
+ SOURCES ${inputs}
74
+ )
75
+
76
+ set_target_properties(${shader_target} PROPERTIES EXCLUDE_FROM_ALL "FALSE")
77
+
78
+ set(SHADER_SOURCES ${SHADER_SOURCES} ${outputs} PARENT_SCOPE)
79
+
80
+ endfunction()
third_party/ktx-src/tests/loadtests/geom/cube.h ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright 2016-2020 Mark Callow
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ static const float cube_face[] =
7
+ {
8
+ -1.0f, +1.0f, +1.0f, /* Front */
9
+ +1.0f, -1.0f, +1.0f,
10
+ +1.0f, +1.0f, +1.0f,
11
+ -1.0f, -1.0f, +1.0f,
12
+ -1.0f, +1.0f, -1.0f, /* Back */
13
+ +1.0f, -1.0f, -1.0f,
14
+ +1.0f, +1.0f, -1.0f,
15
+ -1.0f, -1.0f, -1.0f,
16
+ +1.0f, -1.0f, +1.0f, /* Right */
17
+ +1.0f, +1.0f, -1.0f,
18
+ +1.0f, +1.0f, +1.0f,
19
+ +1.0f, -1.0f, -1.0f,
20
+ -1.0f, -1.0f, +1.0f, /* Left */
21
+ -1.0f, +1.0f, -1.0f,
22
+ -1.0f, +1.0f, +1.0f,
23
+ -1.0f, -1.0f, -1.0f,
24
+ -1.0f, -1.0f, +1.0f, /* Bottom */
25
+ +1.0f, -1.0f, -1.0f,
26
+ +1.0f, -1.0f, +1.0f,
27
+ -1.0f, -1.0f, -1.0f,
28
+ -1.0f, +1.0f, +1.0f, /* Top */
29
+ +1.0f, +1.0f, -1.0f,
30
+ +1.0f, +1.0f, +1.0f,
31
+ -1.0f, +1.0f, -1.0f,
32
+ };
33
+ #define CUBE_NUM_FACE_COMPONENTS 3
34
+ #define CUBE_FACE_STRIDE (sizeof(float) * CUBE_NUM_FACE_COMPONENTS)
35
+
36
+ static const float cube_color[] = /* almost random colors */
37
+ {
38
+ 0.7f, 0.1f, 0.2f, 0.0f, 0.8f, 0.9f, 0.3f, 0.0f, 0.4f, 1.0f, 0.5f, 0.0f, 0.0f, 0.6f, 0.1f, 0.0f,
39
+ 0.8f, 0.2f, 0.3f, 0.0f, 0.9f, 1.0f, 0.4f, 0.0f, 0.5f, 0.0f, 0.6f, 0.0f, 0.1f, 0.7f, 0.2f, 0.0f,
40
+ 0.9f, 0.3f, 0.4f, 0.0f, 1.0f, 0.0f, 0.5f, 0.0f, 0.6f, 0.1f, 0.7f, 0.0f, 0.2f, 0.8f, 0.3f, 0.0f,
41
+ 1.0f, 0.4f, 0.5f, 0.0f, 0.0f, 0.1f, 0.6f, 0.0f, 0.7f, 0.2f, 0.8f, 0.0f, 0.3f, 0.9f, 0.4f, 0.0f,
42
+ 0.0f, 0.5f, 0.6f, 0.0f, 0.1f, 0.2f, 0.7f, 0.0f, 0.8f, 0.3f, 0.9f, 0.0f, 0.4f, 1.0f, 0.5f, 0.0f,
43
+ 0.1f, 0.6f, 0.7f, 0.0f, 0.2f, 0.3f, 0.8f, 0.0f, 0.9f, 0.4f, 1.0f, 0.0f, 0.5f, 0.0f, 0.6f, 0.0f,
44
+ };
45
+ static const float cube_texture[] =
46
+ {
47
+ 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
48
+ 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
49
+ 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
50
+ 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
51
+ 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
52
+ 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f
53
+ };
54
+ static const float cube_normal[] =
55
+ {
56
+ 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f,
57
+ 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f,
58
+ +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f,
59
+ -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
60
+ 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f,
61
+ 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f,
62
+ };
63
+
64
+ static const unsigned short cube_index_buffer[] = {
65
+ 0, 3, 1, 2, 0, 1, /* Front */
66
+ 6, 5, 4, 5, 7, 4, /* Back */
67
+ 8,11, 9,10, 8, 9, /* Right */
68
+ 15,12,13,12,14,13, /* Left */
69
+ 16,19,17,18,16,17, /* Bottom */
70
+ 23,20,21,20,22,21 /* Top */
71
+ };
72
+ #define CUBE_NUM_INDICES (sizeof(cube_index_buffer) / sizeof(unsigned short))
third_party/ktx-src/tests/loadtests/geom/cube_data.h ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Vulkan Samples
3
+ *
4
+ * Copyright 2015-2016 Valve Corporation
5
+ * Copyright 2015-2016 LunarG, Inc.
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+
9
+ //--------------------------------------------------------------------------------------
10
+ // Mesh and VertexFormat Data
11
+ //--------------------------------------------------------------------------------------
12
+ struct Vertex {
13
+ float posX, posY, posZ, posW; // Position data
14
+ float r, g, b, a; // Color
15
+ };
16
+
17
+ struct VertexUV {
18
+ float posX, posY, posZ, posW; // Position data
19
+ float u, v; // texture u,v
20
+ };
21
+
22
+ #define XYZ1(_x_, _y_, _z_) (_x_), (_y_), (_z_), 1.f
23
+ #define UV(_u_, _v_) (_u_), (_v_)
24
+
25
+ static const Vertex g_vbData[] = {
26
+ {XYZ1(-1, -1, -1), XYZ1(0.f, 0.f, 0.f)},
27
+ {XYZ1(1, -1, -1), XYZ1(1.f, 0.f, 0.f)},
28
+ {XYZ1(-1, 1, -1), XYZ1(0.f, 1.f, 0.f)},
29
+ {XYZ1(-1, 1, -1), XYZ1(0.f, 1.f, 0.f)},
30
+ {XYZ1(1, -1, -1), XYZ1(1.f, 0.f, 0.f)},
31
+ {XYZ1(1, 1, -1), XYZ1(1.f, 1.f, 0.f)},
32
+
33
+ {XYZ1(-1, -1, 1), XYZ1(0.f, 0.f, 1.f)},
34
+ {XYZ1(-1, 1, 1), XYZ1(0.f, 1.f, 1.f)},
35
+ {XYZ1(1, -1, 1), XYZ1(1.f, 0.f, 1.f)},
36
+ {XYZ1(1, -1, 1), XYZ1(1.f, 0.f, 1.f)},
37
+ {XYZ1(-1, 1, 1), XYZ1(0.f, 1.f, 1.f)},
38
+ {XYZ1(1, 1, 1), XYZ1(1.f, 1.f, 1.f)},
39
+
40
+ {XYZ1(1, 1, 1), XYZ1(1.f, 1.f, 1.f)},
41
+ {XYZ1(1, 1, -1), XYZ1(1.f, 1.f, 0.f)},
42
+ {XYZ1(1, -1, 1), XYZ1(1.f, 0.f, 1.f)},
43
+ {XYZ1(1, -1, 1), XYZ1(1.f, 0.f, 1.f)},
44
+ {XYZ1(1, 1, -1), XYZ1(1.f, 1.f, 0.f)},
45
+ {XYZ1(1, -1, -1), XYZ1(1.f, 0.f, 0.f)},
46
+
47
+ {XYZ1(-1, 1, 1), XYZ1(0.f, 1.f, 1.f)},
48
+ {XYZ1(-1, -1, 1), XYZ1(0.f, 0.f, 1.f)},
49
+ {XYZ1(-1, 1, -1), XYZ1(0.f, 1.f, 0.f)},
50
+ {XYZ1(-1, 1, -1), XYZ1(0.f, 1.f, 0.f)},
51
+ {XYZ1(-1, -1, 1), XYZ1(0.f, 0.f, 1.f)},
52
+ {XYZ1(-1, -1, -1), XYZ1(0.f, 0.f, 0.f)},
53
+
54
+ {XYZ1(1, 1, 1), XYZ1(1.f, 1.f, 1.f)},
55
+ {XYZ1(-1, 1, 1), XYZ1(0.f, 1.f, 1.f)},
56
+ {XYZ1(1, 1, -1), XYZ1(1.f, 1.f, 0.f)},
57
+ {XYZ1(1, 1, -1), XYZ1(1.f, 1.f, 0.f)},
58
+ {XYZ1(-1, 1, 1), XYZ1(0.f, 1.f, 1.f)},
59
+ {XYZ1(-1, 1, -1), XYZ1(0.f, 1.f, 0.f)},
60
+
61
+ {XYZ1(1, -1, 1), XYZ1(1.f, 0.f, 1.f)},
62
+ {XYZ1(1, -1, -1), XYZ1(1.f, 0.f, 0.f)},
63
+ {XYZ1(-1, -1, 1), XYZ1(0.f, 0.f, 1.f)},
64
+ {XYZ1(-1, -1, 1), XYZ1(0.f, 0.f, 1.f)},
65
+ {XYZ1(1, -1, -1), XYZ1(1.f, 0.f, 0.f)},
66
+ {XYZ1(-1, -1, -1), XYZ1(0.f, 0.f, 0.f)},
67
+ };
68
+
69
+ static const Vertex g_vb_solid_face_colors_Data[] = {
70
+ {XYZ1(-1, -1, -1), XYZ1(1.f, 0.f, 0.f)},
71
+ {XYZ1(1, -1, -1), XYZ1(1.f, 0.f, 0.f)},
72
+ {XYZ1(-1, 1, -1), XYZ1(1.f, 0.f, 0.f)},
73
+ {XYZ1(-1, 1, -1), XYZ1(1.f, 0.f, 0.f)},
74
+ {XYZ1(1, -1, -1), XYZ1(1.f, 0.f, 0.f)},
75
+ {XYZ1(1, 1, -1), XYZ1(1.f, 0.f, 0.f)},
76
+
77
+ {XYZ1(-1, -1, 1), XYZ1(0.f, 1.f, 0.f)},
78
+ {XYZ1(-1, 1, 1), XYZ1(0.f, 1.f, 0.f)},
79
+ {XYZ1(1, -1, 1), XYZ1(0.f, 1.f, 0.f)},
80
+ {XYZ1(1, -1, 1), XYZ1(0.f, 1.f, 0.f)},
81
+ {XYZ1(-1, 1, 1), XYZ1(0.f, 1.f, 0.f)},
82
+ {XYZ1(1, 1, 1), XYZ1(0.f, 1.f, 0.f)},
83
+
84
+ {XYZ1(1, 1, 1), XYZ1(0.f, 0.f, 1.f)},
85
+ {XYZ1(1, 1, -1), XYZ1(0.f, 0.f, 1.f)},
86
+ {XYZ1(1, -1, 1), XYZ1(0.f, 0.f, 1.f)},
87
+ {XYZ1(1, -1, 1), XYZ1(0.f, 0.f, 1.f)},
88
+ {XYZ1(1, 1, -1), XYZ1(0.f, 0.f, 1.f)},
89
+ {XYZ1(1, -1, -1), XYZ1(0.f, 0.f, 1.f)},
90
+
91
+ {XYZ1(-1, 1, 1), XYZ1(1.f, 1.f, 0.f)},
92
+ {XYZ1(-1, -1, 1), XYZ1(1.f, 1.f, 0.f)},
93
+ {XYZ1(-1, 1, -1), XYZ1(1.f, 1.f, 0.f)},
94
+ {XYZ1(-1, 1, -1), XYZ1(1.f, 1.f, 0.f)},
95
+ {XYZ1(-1, -1, 1), XYZ1(1.f, 1.f, 0.f)},
96
+ {XYZ1(-1, -1, -1), XYZ1(1.f, 1.f, 0.f)},
97
+
98
+ {XYZ1(1, 1, 1), XYZ1(1.f, 0.f, 1.f)},
99
+ {XYZ1(-1, 1, 1), XYZ1(1.f, 0.f, 1.f)},
100
+ {XYZ1(1, 1, -1), XYZ1(1.f, 0.f, 1.f)},
101
+ {XYZ1(1, 1, -1), XYZ1(1.f, 0.f, 1.f)},
102
+ {XYZ1(-1, 1, 1), XYZ1(1.f, 0.f, 1.f)},
103
+ {XYZ1(-1, 1, -1), XYZ1(1.f, 0.f, 1.f)},
104
+
105
+ {XYZ1(1, -1, 1), XYZ1(0.f, 1.f, 1.f)},
106
+ {XYZ1(1, -1, -1), XYZ1(0.f, 1.f, 1.f)},
107
+ {XYZ1(-1, -1, 1), XYZ1(0.f, 1.f, 1.f)},
108
+ {XYZ1(-1, -1, 1), XYZ1(0.f, 1.f, 1.f)},
109
+ {XYZ1(1, -1, -1), XYZ1(0.f, 1.f, 1.f)},
110
+ {XYZ1(-1, -1, -1), XYZ1(0.f, 1.f, 1.f)},
111
+ };
112
+
113
+ static const VertexUV g_vb_texture_Data[] = {
114
+ {XYZ1(-1, -1, -1), UV(0.f, 0.f)},
115
+ {XYZ1(-1, 1, 1), UV(1.f, 1.f)},
116
+ {XYZ1(-1, -1, 1), UV(1.f, 0.f)},
117
+ {XYZ1(-1, 1, 1), UV(1.f, 1.f)},
118
+ {XYZ1(-1, -1, -1), UV(0.f, 0.f)},
119
+ {XYZ1(-1, 1, -1), UV(0.f, 1.f)},
120
+
121
+ {XYZ1(-1, -1, -1), UV(1.f, 0.f)},
122
+ {XYZ1(1, -1, -1), UV(0.f, 0.f)},
123
+ {XYZ1(1, 1, -1), UV(0.f, 1.f)},
124
+ {XYZ1(-1, -1, -1), UV(1.f, 0.f)},
125
+ {XYZ1(1, 1, -1), UV(0.f, 1.f)},
126
+ {XYZ1(-1, 1, -1), UV(1.f, 1.f)},
127
+
128
+ {XYZ1(-1, -1, -1), UV(1.f, 1.f)},
129
+ {XYZ1(1, -1, 1), UV(0.f, 0.f)},
130
+ {XYZ1(1, -1, -1), UV(1.f, 0.f)},
131
+ {XYZ1(-1, -1, -1), UV(1.f, 1.f)},
132
+ {XYZ1(-1, -1, 1), UV(0.f, 1.f)},
133
+ {XYZ1(1, -1, 1), UV(0.f, 0.f)},
134
+
135
+ {XYZ1(-1, 1, -1), UV(1.f, 1.f)},
136
+ {XYZ1(1, 1, 1), UV(0.f, 0.f)},
137
+ {XYZ1(-1, 1, 1), UV(0.f, 1.f)},
138
+ {XYZ1(-1, 1, -1), UV(1.f, 1.f)},
139
+ {XYZ1(1, 1, -1), UV(1.f, 0.f)},
140
+ {XYZ1(1, 1, 1), UV(0.f, 0.f)},
141
+
142
+ {XYZ1(1, 1, -1), UV(1.f, 1.f)},
143
+ {XYZ1(1, -1, 1), UV(0.f, 0.f)},
144
+ {XYZ1(1, 1, 1), UV(0.f, 1.f)},
145
+ {XYZ1(1, -1, 1), UV(0.f, 0.f)},
146
+ {XYZ1(1, 1, -1), UV(1.f, 1.f)},
147
+ {XYZ1(1, -1, -1), UV(1.f, 0.f)},
148
+
149
+ {XYZ1(-1, 1, 1), UV(0.f, 1.f)},
150
+ {XYZ1(1, 1, 1), UV(1.f, 1.f)},
151
+ {XYZ1(-1, -1, 1), UV(0.f, 0.f)},
152
+ {XYZ1(-1, -1, 1), UV(0.f, 0.f)},
153
+ {XYZ1(1, 1, 1), UV(1.f, 1.f)},
154
+ {XYZ1(1, -1, 1), UV(1.f, 0.f)},
155
+ };
third_party/ktx-src/tests/loadtests/geom/frame.h ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright 2016-2020 Mark Callow
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ /*
7
+ * Frame definition
8
+ */
9
+ static const GLbyte frame_position[] =
10
+ {
11
+ -1, -1, 0,
12
+ 1, -1, 0,
13
+ 1, 1, 0,
14
+ -1, 1, 0
15
+ };
16
+
17
+ static const GLbyte frame_color[] =
18
+ {
19
+ 1, 1, 0,
20
+ 1, 1, 0,
21
+ 1, 1, 0,
22
+ 1, 1, 0
23
+ };
third_party/ktx-src/tests/loadtests/geom/quad.h ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* -*- tab-width: 4; -*- */
2
+ /* vi: set et sw=2 ts=4 expandtab: */
3
+
4
+ /*
5
+ * Copyright 2016-2020 Mark Callow
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+
9
+ /*
10
+ * Quad definition
11
+ */
12
+ static const GLfloat quad_position[] =
13
+ {
14
+ 1.0f, -1.0f, 0,
15
+ 1.0f, 1.0f, 0,
16
+ -1.0f, -1.0f, 0,
17
+ -1.0f, 1.0f, 0
18
+ };
19
+
20
+ static const GLfloat quad_color[] =
21
+ {
22
+ 0.7f, 0.1f, 0.2f,
23
+ 0.8f, 0.9f, 0.3f,
24
+ 0.4f, 1.0f, 0.5f,
25
+ 0.0f, 0.6f, 0.1f
26
+ };
27
+
28
+ static GLfloat quad_texture[] =
29
+ {
30
+ 1.0f, 0.0f,
31
+ 1.0f, 1.0f,
32
+ 0.0f, 0.0f,
33
+ 0.0f, 1.0f
34
+ };
third_party/ktx-src/tests/loadtests/glloadtests.cmake ADDED
@@ -0,0 +1,449 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2020 Andreas Atteneder
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ set(OPENGL_ES_EMULATOR "" CACHE PATH "Path to OpenGL ES emulation libraries")
5
+
6
+ if(NOT APPLE_LOCKED_OS)
7
+ find_package(OpenGL REQUIRED)
8
+ endif()
9
+ if(WIN32)
10
+ find_package(GLEW REQUIRED)
11
+ endif()
12
+
13
+ function( create_gl_target target version sources common_resources test_images
14
+ KTX_GL_CONTEXT_PROFILE
15
+ KTX_GL_CONTEXT_MAJOR_VERSION KTX_GL_CONTEXT_MINOR_VERSION
16
+ EMULATE_GLES)
17
+
18
+ set( resources ${common_resources};${test_images} )
19
+
20
+ add_executable( ${target}
21
+ ${EXE_FLAG}
22
+ glloadtests.cmake
23
+ ${sources}
24
+ ${resources}
25
+ )
26
+
27
+ set_code_sign(${target})
28
+
29
+ # Nota Bene.
30
+ #
31
+ # 1. With the Visual Studio generator, at least, The SDL and GLEW
32
+ # includes coming from GLAppSDL are being converted to system
33
+ # includes. To see them in VS, view the whole command line in
34
+ # the compile section of the project properties and look at the
35
+ # Additional Options pane at the bottom.
36
+ # 2. GL_APP_SDL's INTERFACE_INCLUDE_DIRECTORIES includes the SYSTEM
37
+ # include from appfwSDL.
38
+ #
39
+ # I do not understand the reasons for either of these.
40
+ target_include_directories(
41
+ ${target}
42
+ PRIVATE
43
+ $<TARGET_PROPERTY:GLAppSDL,INTERFACE_INCLUDE_DIRECTORIES>
44
+ $<TARGET_PROPERTY:ktx,INTERFACE_INCLUDE_DIRECTORIES>
45
+ $<TARGET_PROPERTY:objUtil,INTERFACE_INCLUDE_DIRECTORIES>
46
+ )
47
+
48
+ set_target_properties(${target} PROPERTIES
49
+ CXX_VISIBILITY_PRESET ${STATIC_APP_LIB_SYMBOL_VISIBILITY}
50
+ )
51
+
52
+
53
+ target_link_libraries(
54
+ ${target}
55
+ objUtil
56
+ GLAppSDL
57
+ appfwSDL
58
+ ktx
59
+ )
60
+
61
+ if(NOT EMSCRIPTEN AND NOT EMULATE_GLES)
62
+ target_link_libraries(
63
+ ${target}
64
+ ${OPENGL_LIBRARIES}
65
+ )
66
+ endif()
67
+
68
+ if(APPLE)
69
+ if(IOS)
70
+ # This is location where CMake puts the configured Info.plist.
71
+ # I have not found a CMake variable for this.
72
+ set( launch_screen ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${target}.dir/LaunchScreen.storyboard )
73
+ configure_file( glloadtests/resources/ios/LaunchScreen.storyboard.in
74
+ ${launch_screen}
75
+ )
76
+ set( INFO_PLIST_IN "${PROJECT_SOURCE_DIR}/tests/loadtests/glloadtests/resources/ios/Info.plist.in" )
77
+ set( icon_launch_assets
78
+ ${PROJECT_SOURCE_DIR}/icons/ios/CommonIcons.xcassets
79
+ glloadtests/resources/ios/LaunchImages.xcassets
80
+ ${launch_screen}
81
+ )
82
+ target_sources( ${target}
83
+ PRIVATE
84
+ ${PROJECT_SOURCE_DIR}/icons/ios/CommonIcons.xcassets
85
+ glloadtests/resources/ios/LaunchImages.xcassets
86
+ glloadtests/resources/ios/LaunchScreen.storyboard.in
87
+ )
88
+ # Add to resources so they'll be copied to the bundle.
89
+ list( APPEND resources ${icon_launch_assets} )
90
+ target_link_libraries(
91
+ ${target}
92
+ ${AudioToolbox_LIBRARY}
93
+ ${AVFoundation_LIBRARY}
94
+ ${CoreAudio_LIBRARY}
95
+ ${CoreBluetooth_LIBRARY}
96
+ ${CoreGraphics_LIBRARY}
97
+ ${CoreMotion_LIBRARY}
98
+ ${CoreHaptics_LIBRARY}
99
+ ${Foundation_LIBRARY}
100
+ ${GameController_LIBRARY}
101
+ ${Metal_LIBRARY}
102
+ ${OpenGLES_LIBRARY}
103
+ ${QuartzCore_LIBRARY}
104
+ ${UIKit_LIBRARY}
105
+ )
106
+ else()
107
+ set( INFO_PLIST_IN "${PROJECT_SOURCE_DIR}/tests/loadtests/glloadtests/resources/mac/Info.plist.in" )
108
+ endif()
109
+ elseif(EMSCRIPTEN)
110
+ # Beware of de-duplication in list expansion for commands and options.
111
+ # SHELL: prevents it but if they are separate items in the list they
112
+ # be de-duplicated.
113
+ list( TRANSFORM test_images REPLACE
114
+ "(${PROJECT_SOURCE_DIR}/tests/testimages/([a-zA-Z0-9_].*$))"
115
+ "SHELL:--preload-file \\1@\\2"
116
+ OUTPUT_VARIABLE preloads
117
+ )
118
+ target_link_options(
119
+ ${target}
120
+ PRIVATE
121
+ "SHELL:--source-map-base ./"
122
+ ${preloads}
123
+ "SHELL:--exclude-file '${PROJECT_SOURCE_DIR}/tests/testimages/cubemap*'"
124
+ "SHELL:--use-port=sdl3"
125
+ "SHELL:-s ALLOW_MEMORY_GROWTH=1"
126
+ "SHELL:-s DISABLE_EXCEPTION_CATCHING=0"
127
+ "SHELL:-s USE_WEBGL2=1"
128
+ )
129
+ elseif(WIN32)
130
+ target_sources(
131
+ ${target}
132
+ PRIVATE
133
+ glloadtests/resources/win/glloadtests.rc
134
+ glloadtests/resources/win/resource.h
135
+ )
136
+ if(EMULATE_GLES)
137
+ if (KTX_GL_CONTEXT_MAJOR_VERSION EQUAL 1)
138
+ target_link_libraries(
139
+ ${target}
140
+ "${OPENGL_ES_EMULATOR}/libGLES_CM.lib"
141
+ "${OPENGL_ES_EMULATOR}/libEGL.lib"
142
+ )
143
+ else()
144
+ target_link_libraries(
145
+ ${target}
146
+ "${OPENGL_ES_EMULATOR}/libGLESv2.lib"
147
+ "${OPENGL_ES_EMULATOR}/libEGL.lib"
148
+ )
149
+ endif()
150
+ else()
151
+ target_link_libraries(
152
+ ${target}
153
+ ${GLEW_LIBRARIES}
154
+ )
155
+ endif()
156
+ ensure_runtime_dependencies_windows(${target})
157
+ elseif(LINUX)
158
+ # The output file is configured at CMake config time.
159
+ configure_file(glloadtests/resources/linux/glloadtests.desktop.in
160
+ ${CMAKE_CURRENT_BINARY_DIR}/${target}.desktop
161
+ )
162
+ target_sources(
163
+ ${target}
164
+ PRIVATE
165
+ # Put the input file in sources as that is what must be edited.
166
+ glloadtests/resources/linux/glloadtests.desktop.in
167
+ #${CMAKE_CURRENT_BINARY_DIR}/${target}.desktop
168
+ )
169
+ endif()
170
+
171
+ target_link_libraries( ${target} ${LOAD_TEST_COMMON_LIBS} )
172
+
173
+ if(NOT EMULATE_GLES OR KTX_GL_CONTEXT_MAJOR_VERSION GREATER 1)
174
+ target_compile_definitions(
175
+ ${target}
176
+ PRIVATE
177
+ $<TARGET_PROPERTY:ktx,INTERFACE_COMPILE_DEFINITIONS>
178
+ GL_CONTEXT_PROFILE=${KTX_GL_CONTEXT_PROFILE}
179
+ GL_CONTEXT_MAJOR_VERSION=${KTX_GL_CONTEXT_MAJOR_VERSION}
180
+ GL_CONTEXT_MINOR_VERSION=${KTX_GL_CONTEXT_MINOR_VERSION}
181
+ $<$<PLATFORM_ID:Windows>:NOMINMAX>
182
+ )
183
+ else()
184
+ target_compile_definitions(
185
+ ${target}
186
+ PRIVATE
187
+ $<TARGET_PROPERTY:ktx,INTERFACE_COMPILE_DEFINITIONS>
188
+ $<$<PLATFORM_ID:Windows>:NOMINMAX>
189
+ )
190
+ endif()
191
+
192
+ set_target_properties( ${target} PROPERTIES RESOURCE "${resources}" )
193
+
194
+ if(APPLE)
195
+ set(product_name "${target}")
196
+ set( bundle_identifier org.khronos.ktx.${product_name} )
197
+ # This property must be set to avoid an Xcode warning.
198
+ set_target_properties(${target} PROPERTIES XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "org.khronos.ktx.${product_name}")
199
+ # See important comment about MACOSX_BUNDLE_INFO_PLIST and these
200
+ # properties in ./vkloadtests.cmake.
201
+ set_target_properties( ${target} PROPERTIES
202
+ MACOSX_BUNDLE_BUNDLE_NAME ${product_name}
203
+ MACOSX_BUNDLE_EXECUTABLE_NAME ${product_name}
204
+ MACOSX_BUNDLE_COPYRIGHT "© 2024 Khronos Group, Inc."
205
+ MACOSX_BUNDLE_GUI_IDENTIFIER ${bundle_identifier}
206
+ MACOSX_BUNDLE_INFO_PLIST ${INFO_PLIST_IN}
207
+ MACOSX_BUNDLE_INFO_STRING "View KTX textures; display via OpenGL."
208
+ MACOSX_BUNDLE_ICON_FILE ${KTX_APP_ICON}
209
+ MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
210
+ MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION}
211
+ # Because libassimp is built with bitcode disabled. It's not
212
+ # important unless submitting to the App Store and currently
213
+ # bitcode is optional.
214
+ XCODE_ATTRIBUTE_ENABLE_BITCODE "NO"
215
+ XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH "YES"
216
+ XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME ${KTX_APP_ICON_BASENAME}
217
+ XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2" # iPhone and iPad
218
+ )
219
+ unset(product_name)
220
+ unset(bundle_identifier)
221
+
222
+ # The generated project code for building an Apple bundle automatically
223
+ # copies the executable and all files with the RESOURCE property to the
224
+ # bundle adjusting for the difference in bundle layout between iOS &
225
+ # macOS.
226
+
227
+ if(NOT IOS)
228
+ set_target_properties( ${target} PROPERTIES
229
+ INSTALL_RPATH "@executable_path/../Frameworks"
230
+ )
231
+
232
+ if(BUILD_SHARED_LIBS)
233
+ add_custom_command( TARGET ${target} POST_BUILD
234
+ COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:ktx> "$<TARGET_BUNDLE_CONTENT_DIR:${target}>/Frameworks/$<TARGET_FILE_NAME:ktx>"
235
+ COMMAND ${CMAKE_COMMAND} -E create_symlink $<TARGET_FILE_NAME:ktx> "$<TARGET_BUNDLE_CONTENT_DIR:${target}>/Frameworks/$<TARGET_SONAME_FILE_NAME:ktx>"
236
+ COMMENT "Copy KTX library to build destination"
237
+ )
238
+ endif()
239
+ # Re. SDL3 & assimp: no copy required.: vcpkg libs are static or else
240
+ # vcpkg arranges copy. Brew libs cannot be bundled.
241
+
242
+ # Specify destination for cmake --install.
243
+ install(TARGETS ${target}
244
+ BUNDLE
245
+ DESTINATION /Applications
246
+ COMPONENT GlLoadTestApps
247
+ )
248
+
249
+ endif()
250
+
251
+ else()
252
+ if(EMSCRIPTEN)
253
+ set_target_properties(${target} PROPERTIES SUFFIX ".html")
254
+ endif()
255
+
256
+ # This copies the resources next to the executable for ease
257
+ # of use during debugging and testing.
258
+ add_custom_command( TARGET ${target} POST_BUILD
259
+ COMMAND ${CMAKE_COMMAND} -E make_directory
260
+ $<TARGET_FILE_DIR:${target}>/../resources
261
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
262
+ ${resources}
263
+ $<TARGET_FILE_DIR:${target}>/../resources
264
+ )
265
+
266
+ # See important comment and TODO:s starting at line 365
267
+ # in ./vkloadtests.cmake regarding installation of these
268
+ # targets. Search for "keep the resources".
269
+
270
+ set_target_properties( ${target} PROPERTIES
271
+ INSTALL_RPATH "\$ORIGIN;${CMAKE_INSTALL_FULL_LIBDIR}"
272
+ )
273
+
274
+ ######### IMPORTANT ######
275
+ # When installing via `cmake --install` ALSO install the
276
+ # library component. There seems no way to make a dependency.
277
+ ##########################
278
+ # set( destroot "${LOAD_TEST_DESTROOT}/$<TARGET_FILE_NAME:${target}>")
279
+ # NOTE: WHEN RUNNING MANUAL INSTALLS INSTALL library COMPONENT TOO.
280
+ # install(TARGETS ${target}
281
+ # RUNTIME
282
+ # DESTINATION ${destroot}/bin
283
+ # COMPONENT GlLoadTestApps
284
+ # LIBRARY
285
+ # DESTINATION ${CMAKE_INSTALL_LIBDIR}
286
+ # COMPONENT GlLoadTestApps
287
+ # RESOURCE
288
+ # DESTINATION ${destroot}/resources
289
+ # COMPONENT GlLoadTestApps
290
+ # )
291
+ # install(TARGETS ktx
292
+ # RUNTIME
293
+ # DESTINATION ${destroot}/bin
294
+ # COMPONENT GlLoadTestApps
295
+ # LIBRARY
296
+ # DESTINATION ${destroot}/lib
297
+ # COMPONENT GlLoadTestApps
298
+ # )
299
+ # if(LINUX)
300
+ # # Add a link from the regular bin directory to put command
301
+ # # on PATH.
302
+ # install(CODE "
303
+ # EXECUTE_PROCESS(COMMAND ln -s ${destroot}/bin/$<TARGET_FILE_NAME:${target}> ${CMAKE_INSTALL_FULL_BINDIR}
304
+ # )"
305
+ # COMPONENT GlLoadTestApps
306
+ # )
307
+ # install(FILES
308
+ # ${CMAKE_CURRENT_BINARY_DIR}/${target}.desktop
309
+ # DESTINATION /usr/share/applications
310
+ # COMPONENT GlLoadTestApps
311
+ # )
312
+ # endif(LINUX)
313
+ endif()
314
+ endfunction( create_gl_target target )
315
+
316
+
317
+ set( ES1_TEST_IMAGES
318
+ no-npot.ktx
319
+ hi_mark.ktx
320
+ luminance-reference-metadata.ktx
321
+ orient-up-metadata.ktx
322
+ orient-down-metadata.ktx
323
+ etc1.ktx
324
+ etc2-rgb.ktx
325
+ etc2-rgba1.ktx
326
+ etc2-rgba8.ktx
327
+ rgba-reference.ktx
328
+ rgb-reference.ktx
329
+ rgb-amg-reference.ktx
330
+ rgb-mipmap-reference.ktx
331
+ hi_mark_sq.ktx
332
+ )
333
+ list( TRANSFORM ES1_TEST_IMAGES
334
+ PREPEND "${PROJECT_SOURCE_DIR}/tests/testimages/"
335
+ )
336
+
337
+ set( ES1_SOURCES
338
+ glloadtests/gles1/ES1LoadTests.cpp
339
+ glloadtests/gles1/DrawTexture.cpp
340
+ glloadtests/gles1/DrawTexture.h
341
+ glloadtests/gles1/TexturedCube.cpp
342
+ glloadtests/gles1/TexturedCube.h
343
+ )
344
+
345
+ set( GL3_TEST_IMAGES
346
+ etc1s_Iron_Bars_001_normal.ktx2
347
+ uastc_Iron_Bars_001_normal.ktx2
348
+ color_grid_uastc_zstd.ktx2
349
+ color_grid_zstd.ktx2
350
+ color_grid_uastc.ktx2
351
+ color_grid_basis.ktx2
352
+ kodim17_basis.ktx2
353
+ kodim17_basis.ktx2
354
+ FlightHelmet_baseColor_basis.ktx2
355
+ rgba-reference-u.ktx2
356
+ rgba-reference-u.ktx2
357
+ rgba-reference-u.ktx2
358
+ cubemap_goldengate_uastc_rdo4_zstd5_rd.ktx2
359
+ cubemap_yokohama_basis_rd.ktx2
360
+ orient-down-metadata-u.ktx2
361
+ orient-down-metadata-u.ktx2
362
+ texturearray_bc3_unorm.ktx2
363
+ texturearray_astc_8x8_unorm.ktx2
364
+ texturearray_etc2_unorm.ktx2
365
+ 3dtex_7_reference_u.ktx2
366
+ rgb-mipmap-reference-u.ktx2
367
+ hi_mark.ktx
368
+ orient-up-metadata.ktx
369
+ orient-down-metadata.ktx
370
+ not4_rgb888_srgb.ktx
371
+ etc1.ktx
372
+ etc2-rgb.ktx
373
+ etc2-rgba1.ktx
374
+ etc2-rgba8.ktx
375
+ etc2-sRGB.ktx
376
+ etc2-sRGBa1.ktx
377
+ etc2-sRGBa8.ktx
378
+ rgba-reference.ktx
379
+ rgb-reference.ktx
380
+ conftestimage_R11_EAC.ktx
381
+ conftestimage_SIGNED_R11_EAC.ktx
382
+ conftestimage_RG11_EAC.ktx
383
+ conftestimage_SIGNED_RG11_EAC.ktx
384
+ texturearray_bc3_unorm.ktx
385
+ texturearray_astc_8x8_unorm.ktx
386
+ texturearray_etc2_unorm.ktx
387
+ rgb-amg-reference.ktx
388
+ rgb-mipmap-reference.ktx
389
+ hi_mark_sq.ktx
390
+ )
391
+ list( TRANSFORM GL3_TEST_IMAGES
392
+ PREPEND "${PROJECT_SOURCE_DIR}/tests/testimages/"
393
+ )
394
+ set( GL3_RESOURCE_FILES ${LOAD_TEST_COMMON_RESOURCE_FILES} ${GL3_TEST_IMAGES} )
395
+
396
+ set( GL3_SOURCES
397
+ common/TranscodeTargetStrToFmt.cpp
398
+ common/TranscodeTargetStrToFmt.h
399
+ common/disable_glm_warnings.h
400
+ common/reenable_warnings.h
401
+ glloadtests/shader-based/DrawTexture.cpp
402
+ glloadtests/shader-based/DrawTexture.h
403
+ glloadtests/shader-based/EncodeTexture.cpp
404
+ glloadtests/shader-based/EncodeTexture.h
405
+ glloadtests/shader-based/GL3LoadTests.cpp
406
+ glloadtests/shader-based/GL3LoadTestSample.cpp
407
+ glloadtests/shader-based/GL3LoadTestSample.h
408
+ glloadtests/shader-based/InstancedSampleBase.cpp
409
+ glloadtests/shader-based/InstancedSampleBase.h
410
+ glloadtests/shader-based/mygl.h
411
+ glloadtests/shader-based/shaders.cpp
412
+ glloadtests/shader-based/Texture3d.cpp
413
+ glloadtests/shader-based/Texture3d.h
414
+ glloadtests/shader-based/TextureArray.cpp
415
+ glloadtests/shader-based/TextureArray.h
416
+ glloadtests/shader-based/TextureMipmap.cpp
417
+ glloadtests/shader-based/TextureMipmap.h
418
+ glloadtests/shader-based/TextureCubemap.cpp
419
+ glloadtests/shader-based/TextureCubemap.h
420
+ glloadtests/shader-based/TexturedCube.cpp
421
+ glloadtests/shader-based/TexturedCube.h
422
+ glloadtests/utils/GLMeshLoader.hpp
423
+ glloadtests/utils/GLTextureTranscoder.hpp
424
+ )
425
+
426
+
427
+ if(WIN32)
428
+ if(NOT OPENGL_ES_EMULATOR)
429
+ message("OPENGL_ES_EMULATOR not set. Will not build OpenGL ES load tests applications.")
430
+ else()
431
+ set(EMULATE_GLES ON)
432
+ endif()
433
+ endif()
434
+
435
+ if(IOS OR EMULATE_GLES)
436
+ # OpenGL ES 1.0
437
+ create_gl_target( es1loadtests "ES1" "${ES1_SOURCES}" "${KTX_APP_ICON_PATH}" "${ES1_TEST_IMAGES}" SDL_GL_CONTEXT_PROFILE_ES 1 0 ON)
438
+ endif()
439
+
440
+ if(IOS OR EMSCRIPTEN OR EMULATE_GLES)
441
+ # OpenGL ES 3.0
442
+ create_gl_target( es3loadtests "ES3" "${GL3_SOURCES}" "${LOAD_TEST_COMMON_RESOURCE_FILES}" "${GL3_TEST_IMAGES}" SDL_GL_CONTEXT_PROFILE_ES 3 0 ON YES)
443
+ endif()
444
+
445
+ if( (APPLE AND NOT IOS) OR LINUX OR WIN32 )
446
+ # OpenGL 3.3
447
+ create_gl_target( gl3loadtests "GL3" "${GL3_SOURCES}" "${LOAD_TEST_COMMON_RESOURCE_FILES}" "${GL3_TEST_IMAGES}" SDL_GL_CONTEXT_PROFILE_CORE 3 3 OFF YES)
448
+ endif()
449
+
third_party/ktx-src/tests/loadtests/glloadtests/GLLoadTests.cpp ADDED
@@ -0,0 +1,313 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* -*- tab-width: 4; -*- */
2
+ /* vi: set sw=2 ts=4 expandtab: */
3
+
4
+ /*
5
+ * Copyright 2015-2020 Mark Callow.
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+
9
+ /**
10
+ * @internal
11
+ * @file
12
+ * @~English
13
+ *
14
+ * @brief Implementation of app for running a set of OpenGL load tests.
15
+ */
16
+
17
+ #include <exception>
18
+ #include <sstream>
19
+ #include <ktx.h>
20
+
21
+ #include "GLLoadTests.h"
22
+ #include "ltexceptions.h"
23
+
24
+ GLLoadTests::GLLoadTests(const sampleInvocation samples[],
25
+ const uint32_t numSamples,
26
+ const char* const name,
27
+ const SDL_GLProfile profile,
28
+ const int majorVersion,
29
+ const int minorVersion)
30
+ : GLAppSDL(name, 640, 480, profile, majorVersion, minorVersion),
31
+ siSamples(samples), sampleIndex(numSamples)
32
+ {
33
+ pCurSample = nullptr;
34
+ }
35
+
36
+ GLLoadTests::~GLLoadTests()
37
+ {
38
+ delete pCurSample;
39
+ }
40
+
41
+ bool
42
+ GLLoadTests::initialize(Args& args)
43
+ {
44
+ bool explicitlyLoadOpenGL = false;
45
+ for (uint32_t i = 1; i < args.size(); i++) {
46
+ if (args[i].compare("--load-gl") == 0) {
47
+ explicitlyLoadOpenGL = true;
48
+ args.erase(args.begin() + i);
49
+ break;
50
+ }
51
+ }
52
+
53
+ if (!GLAppSDL::initialize(args))
54
+ return false;
55
+
56
+ // --load-gl allows testing of explicitly loading the OpenGL pointers.
57
+ // Default is for ktxTexture_GLUpload to implicitly load them.
58
+ if (explicitlyLoadOpenGL)
59
+ ktxLoadOpenGL(reinterpret_cast<PFNGLGETPROCADDRESS>(SDL_GL_GetProcAddress));
60
+
61
+ for (auto it = args.begin() + 1; it != args.end(); it++) {
62
+ infiles.push_back(*it);
63
+ }
64
+ if (infiles.size() > 0) {
65
+ sampleIndex.setNumSamples((uint32_t)infiles.size());
66
+ }
67
+ // Launch the first sample.
68
+ invokeSample(Direction::eForward);
69
+ return true;
70
+ }
71
+
72
+
73
+ void
74
+ GLLoadTests::finalize()
75
+ {
76
+ delete pCurSample;
77
+ GLAppSDL::finalize();
78
+ }
79
+
80
+
81
+ bool
82
+ GLLoadTests::doEvent(SDL_Event* event)
83
+ {
84
+ bool result = false;
85
+ switch (event->type) {
86
+ case SDL_EVENT_KEY_UP:
87
+ switch (event->key.key) {
88
+ case 'q':
89
+ quit = true;
90
+ break;
91
+ case 'n':
92
+ ++sampleIndex;
93
+ invokeSample(Direction::eForward);
94
+ break;
95
+ case 'p':
96
+ --sampleIndex;
97
+ invokeSample(Direction::eBack);
98
+ break;
99
+ default:
100
+ result = true;
101
+ }
102
+ break;
103
+ case SDL_EVENT_MOUSE_BUTTON_DOWN:
104
+ // Forward to sample in case this is the start of motion.
105
+ result = true;
106
+ switch (event->button.button) {
107
+ case SDL_BUTTON_LEFT:
108
+ buttonDown.x = event->button.x;
109
+ buttonDown.y = event->button.y;
110
+ buttonDown.timestamp = event->button.timestamp;
111
+ break;
112
+ default:
113
+ break;
114
+ }
115
+ break;
116
+ case SDL_EVENT_MOUSE_BUTTON_UP:
117
+ // Forward to sample so it doesn't get stuck in button down state.
118
+ result = true;
119
+ switch (event->button.button) {
120
+ case SDL_BUTTON_LEFT:
121
+ if (SDL_fabs(event->button.x - buttonDown.x) < 5
122
+ && SDL_fabs(event->button.y - buttonDown.y) < 5
123
+ && (event->button.timestamp - buttonDown.timestamp) < 100) {
124
+ // Advance to the next sample.
125
+ ++sampleIndex;
126
+ invokeSample(Direction::eForward);
127
+ }
128
+ break;
129
+ default:
130
+ break;
131
+ }
132
+ break;
133
+ // On macOS drop events come also when Launch Pad sends a file open event.
134
+ case SDL_EVENT_DROP_BEGIN:
135
+ // Opens of multiple selected files from Finder/LaunchPad come as
136
+ // a BEGIN, COMPLETE sequence per file. Only clear infiles after a
137
+ // suitable pause between COMPLETE and BEGIN.
138
+ if (event->drop.timestamp - dropCompleteTime > 500) {
139
+ infiles.clear();
140
+ }
141
+ break;
142
+ case SDL_EVENT_DROP_FILE:
143
+ infiles.push_back(event->drop.data);
144
+ break;
145
+ case SDL_EVENT_DROP_COMPLETE:
146
+ if (!infiles.empty()) {
147
+ // Guard against the drop being text.
148
+ dropCompleteTime = event->drop.timestamp;
149
+ sampleIndex.setNumSamples((uint32_t)infiles.size());
150
+ invokeSample(Direction::eForward);
151
+ }
152
+ break;
153
+ case SDL_EVENT_USER:
154
+ if (event->user.code == SwipeDetector::swipeGesture) {
155
+ // This is horrible.
156
+ uint64_t udirection = reinterpret_cast<uint64_t>(event->user.data1);
157
+ SwipeDetector::Direction direction =
158
+ static_cast<SwipeDetector::Direction>(udirection);
159
+ switch (direction) {
160
+ case SwipeDetector::Direction::left:
161
+ ++sampleIndex;
162
+ invokeSample(Direction::eForward);
163
+ break;
164
+ case SwipeDetector::Direction::right:
165
+ --sampleIndex;
166
+ invokeSample(Direction::eBack);
167
+ break;
168
+ default:
169
+ result = true;
170
+ }
171
+ } else {
172
+ result = true;
173
+ }
174
+ break;
175
+ default:
176
+ result = swipeDetector.doEvent(event);
177
+ }
178
+
179
+ if (result) {
180
+ // Further processing required.
181
+ if (pCurSample != nullptr)
182
+ result = pCurSample->doEvent(event); // Give sample a chance.
183
+ if (result)
184
+ return GLAppSDL::doEvent(event); // Pass to base class.
185
+ }
186
+ return result;
187
+ }
188
+
189
+
190
+ void
191
+ GLLoadTests::windowResized()
192
+ {
193
+ if (pCurSample != nullptr)
194
+ pCurSample->resize(w_width, w_height);
195
+ }
196
+
197
+
198
+ void
199
+ GLLoadTests::drawFrame(uint32_t msTicks)
200
+ {
201
+ if (pCurSample != nullptr)
202
+ pCurSample->run(msTicks);
203
+
204
+ GLAppSDL::drawFrame(msTicks);
205
+ }
206
+
207
+ #if 0
208
+ void
209
+ GLLoadTests::getOverlayText(GLTextOverlay * textOverlay)
210
+ {
211
+ if (enableTextOverlay && pCurSample != nullptr) {
212
+ pCurSample->getOverlayText(textOverlay);
213
+ }
214
+ }
215
+ #endif
216
+
217
+ void
218
+ GLLoadTests::invokeSample(Direction dir)
219
+ {
220
+ const sampleInvocation* sampleInv = &siSamples[sampleIndex];
221
+
222
+ delete pCurSample;
223
+ // Certain events can be triggered during new sample initialization
224
+ // while pCurSample is not valid, e.g. FOCUS_LOST. Protect against
225
+ // problems from this by indicating there is no current sample.
226
+ pCurSample = nullptr;
227
+
228
+ uint32_t unsupportedTypeExceptions = 0;
229
+ std::string fileTitle;
230
+ for (;;) {
231
+ try {
232
+ if (infiles.size() > 0) {
233
+ fileTitle = "Viewing file ";
234
+ fileTitle += infiles[sampleIndex];
235
+ pCurSample = showFile(infiles[sampleIndex]);
236
+ } else {
237
+ sampleInv = &siSamples[sampleIndex];
238
+ pCurSample = sampleInv->createSample(w_width, w_height,
239
+ sampleInv->args,
240
+ sBasePath);
241
+ }
242
+ break;
243
+ } catch (unsupported_ctype& e) {
244
+ (void)e; // To quiet unused variable warnings from some compilers.
245
+ unsupportedTypeExceptions++;
246
+ if (unsupportedTypeExceptions == sampleIndex.getNumSamples()) {
247
+ SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
248
+ infiles.size() > 0 ? fileTitle.c_str() : sampleInv->title,
249
+ "None of the specified samples or files use texture types "
250
+ "supported on this platform.",
251
+ NULL);
252
+ exit(0);
253
+ } else {
254
+ dir == Direction::eForward ? ++sampleIndex : --sampleIndex;
255
+ }
256
+ } catch (std::exception& e) {
257
+ const SDL_MessageBoxButtonData buttons[] = {
258
+ /* .flags, .buttonid, .text */
259
+ { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 0, "Continue" },
260
+ { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 1, "Abort" },
261
+ };
262
+ #if 0
263
+ const SDL_MessageBoxColorScheme colorScheme = {
264
+ { /* .colors (.r, .g, .b) */
265
+ /* [SDL_MESSAGEBOX_COLOR_BACKGROUND] */
266
+ { 255, 0, 0 },
267
+ /* [SDL_MESSAGEBOX_COLOR_TEXT] */
268
+ { 0, 255, 0 },
269
+ /* [SDL_MESSAGEBOX_COLOR_BUTTON_BORDER] */
270
+ { 255, 255, 0 },
271
+ /* [SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND] */
272
+ { 0, 0, 255 },
273
+ /* [SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED] */
274
+ { 255, 0, 255 }
275
+ }
276
+ };
277
+ #endif
278
+ const SDL_MessageBoxData messageboxdata = {
279
+ SDL_MESSAGEBOX_ERROR, // .flags
280
+ NULL, // .window
281
+ infiles.size() > 0 ?
282
+ fileTitle.c_str() : sampleInv->title, // .title
283
+ e.what(), // .message
284
+ SDL_arraysize(buttons), // .numbuttons
285
+ buttons, // .buttons
286
+ NULL //&colorScheme // .colorScheme
287
+ };
288
+ int buttonid;
289
+ if (!SDL_ShowMessageBox(&messageboxdata, &buttonid)) {
290
+ SDL_Log("error displaying error message box");
291
+ exit(1);
292
+ }
293
+ if (buttonid == 0) {
294
+ // Continue
295
+ dir == Direction::eForward ? ++sampleIndex : --sampleIndex;
296
+ } else {
297
+ // We've been told to quit or no button was pressed.
298
+ exit(1);
299
+ }
300
+ }
301
+ }
302
+ setAppTitle(infiles.size() > 0 ? fileTitle.c_str() : sampleInv->title);
303
+ pCurSample->resize(w_width, w_height);
304
+ }
305
+
306
+ void
307
+ GLLoadTests::onFPSUpdate()
308
+ {
309
+ // Using onFPSUpdate avoids rewriting the title every frame.
310
+ //setWindowTitle(pCurSample->title);
311
+ GLAppSDL::onFPSUpdate();
312
+ }
313
+
third_party/ktx-src/tests/loadtests/glloadtests/GLLoadTests.h ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* -*- tab-width: 4; -*- */
2
+ /* vi: set sw=2 ts=4 expandtab: */
3
+
4
+ #ifndef GL_LOAD_TESTS_H
5
+ #define GL_LOAD_TESTS_H
6
+
7
+ /*
8
+ * Copyright 2015-2020 Mark Callow.
9
+ * SPDX-License-Identifier: Apache-2.0
10
+ */
11
+
12
+ /**
13
+ * @internal
14
+ * @file
15
+ * @~English
16
+ *
17
+ * @brief Definition of app for running a set of OpenGL load tests.
18
+ */
19
+
20
+ #include <string>
21
+ #include <vector>
22
+
23
+ #include "GLAppSDL.h"
24
+ #include "LoadTestSample.h"
25
+ #include "SwipeDetector.h"
26
+
27
+ class GLLoadTests : public GLAppSDL {
28
+ public:
29
+ /** A table of samples and arguments */
30
+ typedef struct sampleInvocation_ {
31
+ const LoadTestSample::PFN_create createSample;
32
+ const char* const args;
33
+ const char* const title;
34
+ } sampleInvocation;
35
+
36
+ GLLoadTests(const sampleInvocation samples[],
37
+ const uint32_t numSamples,
38
+ const char* const name,
39
+ const SDL_GLProfile profile,
40
+ const int majorVersion,
41
+ const int minorVersion);
42
+ virtual ~GLLoadTests();
43
+ virtual bool doEvent(SDL_Event* event);
44
+ virtual void drawFrame(uint32_t msTicks);
45
+ virtual void finalize();
46
+ //virtual void getOverlayText(TextOverlay* textOverlay, float yOffset);
47
+ virtual bool initialize(Args& args);
48
+ virtual void onFPSUpdate();
49
+ virtual void windowResized();
50
+
51
+ protected:
52
+ enum class Direction {
53
+ eForward,
54
+ eBack
55
+ };
56
+ void invokeSample(Direction dir);
57
+ LoadTestSample* showFile(const std::string& filename);
58
+ LoadTestSample* pCurSample;
59
+
60
+ bool quit = false;
61
+
62
+ const sampleInvocation* const siSamples;
63
+ class sampleIndex {
64
+ public:
65
+ sampleIndex(const uint32_t numSamples) : numSamples(numSamples) {
66
+ index = 0;
67
+ }
68
+ sampleIndex& operator++() {
69
+ if (++index >= numSamples)
70
+ index = 0;
71
+ return *this;
72
+ }
73
+ sampleIndex& operator--() {
74
+ if (--index > numSamples /* underflow */)
75
+ index = numSamples-1;
76
+ return *this;
77
+ }
78
+ operator int32_t() {
79
+ return index;
80
+ }
81
+ uint32_t getNumSamples() { return numSamples; }
82
+ void setNumSamples(uint32_t ns) { numSamples = ns; }
83
+ protected:
84
+ uint32_t numSamples;
85
+ uint32_t index;
86
+ } sampleIndex;
87
+
88
+ std::vector<std::string> infiles;
89
+
90
+ Sint64 dropCompleteTime = 0;
91
+ struct {
92
+ float x;
93
+ float y;
94
+ Sint64 timestamp;
95
+ } buttonDown;
96
+
97
+ SwipeDetector swipeDetector;
98
+ };
99
+
100
+ #endif /* GL_LOAD_TESTS_H */
third_party/ktx-src/tests/loadtests/glloadtests/gles1/DrawTexture.cpp ADDED
@@ -0,0 +1,250 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* -*- tab-width: 4; -*- */
2
+ /* vi: set sw=2 ts=4 expandtab: */
3
+
4
+ /*
5
+ * Copyright 2018-2020 Mark Callow.
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+
9
+ /**
10
+ * @file DrawTexture.cpp
11
+ * @brief Draw textures at actual size using the DrawTexture functions
12
+ * from OES_draw_texture.
13
+ *
14
+ * @author Mark Callow
15
+ */
16
+
17
+
18
+ #if defined(_WIN32)
19
+ #if _MSC_VER < 1900
20
+ #define snprintf _snprintf
21
+ #endif
22
+ #define _CRT_SECURE_NO_WARNINGS
23
+ #endif
24
+
25
+ #include <iomanip>
26
+ #include <sstream>
27
+ #include <ktx.h>
28
+ #include "disable_glm_warnings.h"
29
+ #include <glm/gtc/matrix_transform.hpp>
30
+ #include <glm/gtc/type_ptr.hpp>
31
+ #include "reenable_warnings.h"
32
+
33
+ #include "DrawTexture.h"
34
+ #include "frame.h"
35
+
36
+ /* ------------------------------------------------------------------------ */
37
+
38
+ #if 0
39
+ static int isPowerOfTwo (int x)
40
+ {
41
+ if (x < 0) x = -1;
42
+ return ((x != 0) && !(x & (x - 1)));
43
+ }
44
+ #endif
45
+
46
+ /* ------------------------------------------------------------------------ */
47
+
48
+ LoadTestSample*
49
+ DrawTexture::create(uint32_t width, uint32_t height,
50
+ const char* const szArgs,
51
+ const std::string sBasePath)
52
+ {
53
+ return new DrawTexture(width, height, szArgs, sBasePath);
54
+ }
55
+
56
+ DrawTexture::DrawTexture(uint32_t width, uint32_t height,
57
+ const char* const szArgs,
58
+ const std::string sBasePath)
59
+ : LoadTestSample(width, height, sBasePath)
60
+ {
61
+ GLint iCropRect[4] = {0, 0, 0, 0};
62
+ const GLchar* szExtensions = (const GLchar*)glGetString(GL_EXTENSIONS);
63
+ const char* filename;
64
+ std::string pathname;
65
+ GLenum target;
66
+ GLboolean npotTexture;
67
+ GLenum glerror;
68
+ ktxTexture* kTexture;
69
+ KTX_error_code ktxresult;
70
+ GLint sign_s = 1, sign_t = 1;
71
+
72
+ bInitialized = false;
73
+ gnTexture = 0;
74
+
75
+
76
+ if (strstr(szExtensions, "OES_draw_texture") != NULL) {
77
+ glDrawTexsOES = (PFNGLDRAWTEXSOESPROC)SDL_GL_GetProcAddress("glDrawTexsOES");
78
+ glDrawTexiOES = (PFNGLDRAWTEXIOESPROC)SDL_GL_GetProcAddress("glDrawTexiOES");
79
+ glDrawTexxOES = (PFNGLDRAWTEXXOESPROC)SDL_GL_GetProcAddress("glDrawTexxOES");
80
+ glDrawTexfOES = (PFNGLDRAWTEXFOESPROC)SDL_GL_GetProcAddress("glDrawTexfOES");
81
+ glDrawTexsvOES = (PFNGLDRAWTEXSVOESPROC)SDL_GL_GetProcAddress("glDrawTexsvOES");
82
+ glDrawTexivOES = (PFNGLDRAWTEXIVOESPROC)SDL_GL_GetProcAddress("glDrawTexivOES");
83
+ glDrawTexxvOES = (PFNGLDRAWTEXXVOESPROC)SDL_GL_GetProcAddress("glDrawTexxvOES");
84
+ glDrawTexfvOES = (PFNGLDRAWTEXFVOESPROC)SDL_GL_GetProcAddress("glDrawTexfvOES");
85
+ } else {
86
+ /* Can't do anything */
87
+ std::stringstream message;
88
+
89
+ message << "DrawTexture: this OpenGL ES implementation does not support"
90
+ << " OES_draw_texture. Can't Run Test";
91
+ throw std::runtime_error(message.str());
92
+ }
93
+
94
+ if (strstr(szExtensions, "OES_texture_npot") != NULL)
95
+ bNpotSupported = GL_TRUE;
96
+ else
97
+ bNpotSupported = GL_FALSE;
98
+
99
+
100
+ if ((filename = strchr(szArgs, ' ')) != NULL) {
101
+ npotTexture = GL_FALSE;
102
+ if (!strncmp(szArgs, "--npot ", 7)) {
103
+ npotTexture = GL_TRUE;
104
+ #if defined(DEBUG)
105
+ } else {
106
+ assert(0); /* Unknown argument in sampleInvocations */
107
+ #endif
108
+ }
109
+ } else {
110
+ filename = szArgs;
111
+ npotTexture = GL_FALSE;
112
+ }
113
+
114
+ if (npotTexture && !bNpotSupported) {
115
+ /* Load error texture. */
116
+ filename = "no-npot.ktx";
117
+ }
118
+
119
+ pathname = getAssetPath() + filename;
120
+
121
+ ktxresult = ktxTexture_CreateFromNamedFile(pathname.c_str(),
122
+ KTX_TEXTURE_CREATE_NO_FLAGS,
123
+ &kTexture);
124
+ if (KTX_SUCCESS != ktxresult) {
125
+ std::stringstream message;
126
+
127
+ message << "Creation of ktxTexture from \"" << pathname
128
+ << "\" failed: " << ktxErrorString(ktxresult);
129
+ throw std::runtime_error(message.str());
130
+ }
131
+ ktxresult = ktxTexture_GLUpload(kTexture, &gnTexture, &target, &glerror);
132
+
133
+ if (KTX_SUCCESS == ktxresult) {
134
+ if (target != GL_TEXTURE_2D) {
135
+ /* Can only draw 2D textures */
136
+ glDeleteTextures(1, &gnTexture);
137
+ return;
138
+ }
139
+
140
+ if (kTexture->orientation.x == KTX_ORIENT_X_LEFT)
141
+ sign_s = -1;
142
+ if (kTexture->orientation.y == KTX_ORIENT_Y_DOWN)
143
+ sign_t = -1;
144
+
145
+ iCropRect[2] = uTexWidth = kTexture->baseWidth;
146
+ iCropRect[3] = uTexHeight = kTexture->baseHeight;
147
+ iCropRect[2] *= sign_s;
148
+ iCropRect[3] *= sign_t;
149
+
150
+ glEnable(target);
151
+
152
+ if (kTexture->numLevels > 1)
153
+ // Enable bilinear mipmapping.
154
+ // TO DO: application can consider inserting a key,value pair in
155
+ // the KTX file that indicates what type of filtering to use.
156
+ glTexParameteri(target,
157
+ GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
158
+ else
159
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
160
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
161
+
162
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
163
+ glTexParameteriv(target, GL_TEXTURE_CROP_RECT_OES, iCropRect);
164
+
165
+ /* Check for any errors */
166
+ assert(GL_NO_ERROR == glGetError());
167
+
168
+ ktxTexture_Destroy(kTexture);
169
+ } else {
170
+ std::stringstream message;
171
+
172
+ message << "Load of texture from \"" << pathname << "\" failed: ";
173
+ if (ktxresult == KTX_GL_ERROR) {
174
+ message << std::showbase << "GL error " << std::hex << glerror
175
+ << "occurred.";
176
+ } else {
177
+ message << ktxErrorString(ktxresult);
178
+ }
179
+ throw std::runtime_error(message.str());
180
+ }
181
+
182
+ glClearColor(0.4f, 0.4f, 0.5f, 1.0f);
183
+ glColor4f(1.0f, 1.0f, 0.0f, 1.0f);
184
+ glEnableClientState(GL_VERTEX_ARRAY);
185
+ glVertexPointer(3, GL_BYTE, 0, (GLvoid *)frame_position);
186
+
187
+ bInitialized = GL_TRUE;
188
+ }
189
+
190
+ /* ------------------------------------------------------------------------ */
191
+
192
+ DrawTexture::~DrawTexture()
193
+ {
194
+ if (bInitialized) {
195
+ glDeleteTextures(1, &gnTexture);
196
+ }
197
+ assert(GL_NO_ERROR == glGetError());
198
+ }
199
+
200
+ /* ------------------------------------------------------------------------ */
201
+
202
+ void
203
+ DrawTexture::resize(uint32_t uNewWidth, uint32_t uNewHeight)
204
+ {
205
+ glViewport(0, 0, uNewWidth, uNewHeight);
206
+ this->uWidth = uNewWidth;
207
+ this->uHeight = uNewHeight;
208
+
209
+ // Set up an orthographic projection where 1 = 1 pixel
210
+ framePMatrix = glm::ortho(0.f, (float)uWidth, 0.f, (float)uHeight);
211
+ // Move (0,0,0) to the center of the window.
212
+ framePMatrix *= glm::translate(glm::mat4(),
213
+ glm::vec3((float)uWidth/2, (float)uHeight/2, 0));
214
+
215
+ glMatrixMode(GL_PROJECTION);
216
+ glLoadMatrixf(glm::value_ptr(framePMatrix));
217
+
218
+ glMatrixMode(GL_MODELVIEW);
219
+ // Scale the frame to fill the viewport. To guarantee its lines
220
+ // appear we need to inset them by half-a-pixel hence the -1.
221
+ // [Lines at the edges of the clip volume may or may not appear
222
+ // depending on the OpenGL ES implementation. This is because
223
+ // (a) the edges are on the points of the diamonds of the diamond
224
+ // exit rule and slight precision errors can easily push the
225
+ // lines outside the diamonds.
226
+ // (b) the specification allows lines to be up to 1 pixel either
227
+ // side of the exact position.]
228
+ glLoadIdentity();
229
+ glScalef((float)(uWidth - 1) / 2, (float)(uHeight - 1) / 2, 1);
230
+ }
231
+
232
+ /* ------------------------------------------------------------------------ */
233
+
234
+ void
235
+ DrawTexture::run(uint32_t /*msTicks*/)
236
+ {
237
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
238
+ glDisable(GL_TEXTURE_2D);
239
+ glDrawArrays(GL_LINE_LOOP, 0, 4);
240
+
241
+ glEnable(GL_TEXTURE_2D);
242
+ glDrawTexiOES(uWidth/2 - uTexWidth/2,
243
+ (uHeight)/2 - uTexHeight/2,
244
+ 0,
245
+ uTexWidth, uTexHeight);
246
+
247
+ assert(GL_NO_ERROR == glGetError());
248
+ }
249
+
250
+ /* ------------------------------------------------------------------------ */
third_party/ktx-src/tests/loadtests/glloadtests/gles1/DrawTexture.h ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* -*- tab-width: 4; -*- */
2
+ /* vi: set sw=2 ts=4 expandtab: */
3
+
4
+ /*
5
+ * Copyright 2018-2020 Mark Callow.
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+
9
+ /**
10
+ * @file DrawTexture.h
11
+ * @brief Draw textures at actual size using the DrawTexture functions
12
+ * from OES_draw_texture.
13
+ *
14
+ * @author Mark Callow
15
+ */
16
+
17
+ #ifndef DRAW_TEXTURE_H
18
+ #define DRAW_TEXTURE_H
19
+
20
+ #include <GLES/gl.h>
21
+ #include <GLES/glext.h>
22
+
23
+ #include "LoadTestSample.h"
24
+
25
+ class DrawTexture : public LoadTestSample {
26
+ public:
27
+ DrawTexture(uint32_t width, uint32_t height,
28
+ const char* const szArgs,
29
+ const std::string sBasePath);
30
+ ~DrawTexture();
31
+
32
+ virtual void resize(uint32_t width, uint32_t height);
33
+ virtual void run(uint32_t msTicks);
34
+
35
+ //virtual void getOverlayText(GLTextOverlay *textOverlay);
36
+
37
+ static LoadTestSample*
38
+ create(uint32_t width, uint32_t height,
39
+ const char* const szArgs, const std::string sBasePath);
40
+
41
+ protected:
42
+ PFNGLDRAWTEXSOESPROC glDrawTexsOES;
43
+ PFNGLDRAWTEXIOESPROC glDrawTexiOES;
44
+ PFNGLDRAWTEXXOESPROC glDrawTexxOES;
45
+ PFNGLDRAWTEXFOESPROC glDrawTexfOES;
46
+ PFNGLDRAWTEXSVOESPROC glDrawTexsvOES;
47
+ PFNGLDRAWTEXIVOESPROC glDrawTexivOES;
48
+ PFNGLDRAWTEXXVOESPROC glDrawTexxvOES;
49
+ PFNGLDRAWTEXFVOESPROC glDrawTexfvOES;
50
+
51
+ uint32_t uWidth;
52
+ uint32_t uHeight;
53
+
54
+ uint32_t uTexWidth;
55
+ uint32_t uTexHeight;
56
+
57
+ glm::mat4 framePMatrix;
58
+
59
+ GLuint gnTexture;
60
+
61
+ bool bNpotSupported;
62
+
63
+ bool bInitialized;
64
+ };
65
+
66
+ #endif /* DRAW_TEXTURE_H */
third_party/ktx-src/tests/loadtests/glloadtests/gles1/ES1LoadTests.cpp ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* -*- tab-width: 4; -*- */
2
+ /* vi: set sw=2 ts=4 expandtab: */
3
+
4
+ /*
5
+ * Copyright 2018-2020 Mark Callow.
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+
9
+ /**
10
+ * @file ES1LoadTests.cpp
11
+ * @brief List of tests of the KTX loader for OpenGL ES 1.1.
12
+ *
13
+ * The loader is tested by loading and drawing KTX textures in various formats
14
+ * using the DrawTexture and TexturedCube samples.
15
+ */
16
+
17
+ #include <sstream>
18
+ #include <ktx.h>
19
+
20
+ #include "GLLoadTests.h"
21
+ #include "DrawTexture.h"
22
+ #include "TexturedCube.h"
23
+
24
+ LoadTestSample*
25
+ GLLoadTests::showFile(const std::string& filename)
26
+ {
27
+ KTX_error_code ktxresult;
28
+ ktxTexture* kTexture;
29
+ ktxresult = ktxTexture_CreateFromNamedFile(filename.c_str(),
30
+ KTX_TEXTURE_CREATE_NO_FLAGS,
31
+ &kTexture);
32
+ if (KTX_SUCCESS != ktxresult) {
33
+ std::stringstream message;
34
+
35
+ message << "Creation of ktxTexture from \"" << getAssetPath()
36
+ << filename << "\" failed: " << ktxErrorString(ktxresult);
37
+ throw std::runtime_error(message.str());
38
+ }
39
+
40
+ LoadTestSample::PFN_create createViewer;
41
+ LoadTestSample* pViewer;
42
+ createViewer = DrawTexture::create;
43
+ ktxTexture_Destroy(kTexture);
44
+ pViewer = createViewer(w_width, w_height, filename.c_str(), "");
45
+ return pViewer;
46
+ }
47
+
48
+ const GLLoadTests::sampleInvocation siSamples[] = {
49
+ { DrawTexture::create,
50
+ "--npot hi_mark.ktx",
51
+ "RGB8 NPOT HI Logo"
52
+ },
53
+ { DrawTexture::create,
54
+ "--npot luminance-reference-metadata.ktx",
55
+ "LUMINANCE8 NPOT"
56
+ },
57
+ { DrawTexture::create,
58
+ "orient-up-metadata.ktx",
59
+ "RGB8 + KTXOrientation up"
60
+ },
61
+ { DrawTexture::create,
62
+ "orient-down-metadata.ktx",
63
+ "RGB8 + KTXOrientation down"
64
+ },
65
+ { DrawTexture::create,
66
+ "etc1.ktx",
67
+ "ETC1 RGB8"
68
+ },
69
+ { DrawTexture::create,
70
+ "etc2-rgb.ktx",
71
+ "ETC2 RGB8"
72
+ },
73
+ { DrawTexture::create,
74
+ "etc2-rgba1.ktx",
75
+ "ETC2 RGB8A1"
76
+ },
77
+ { DrawTexture::create,
78
+ "etc2-rgba8.ktx",
79
+ "ETC2 RGB8A8"
80
+ },
81
+ { DrawTexture::create,
82
+ "rgba-reference.ktx",
83
+ "RGBA8"
84
+ },
85
+ { TexturedCube::create,
86
+ "rgb-reference.ktx",
87
+ "RGB8"
88
+ },
89
+ { TexturedCube::create,
90
+ "rgb-amg-reference.ktx",
91
+ "RGB8 + Auto Mipmap"
92
+ },
93
+ { TexturedCube::create,
94
+ "rgb-mipmap-reference.ktx",
95
+ "RGB8 Color/level mipmap"
96
+ },
97
+ { TexturedCube::create,
98
+ "--npot hi_mark_sq.ktx",
99
+ "RGB8 NPOT HI Logo"
100
+ },
101
+ };
102
+
103
+ const int iNumSamples = sizeof(siSamples) / sizeof(GLLoadTests::sampleInvocation);
104
+
105
+ AppBaseSDL* theApp = new GLLoadTests(siSamples, iNumSamples,
106
+ "KTX Loader Tests for OpenGL ES 1",
107
+ SDL_GL_CONTEXT_PROFILE_ES, 1, 1);
108
+
109
+
third_party/ktx-src/tests/loadtests/glloadtests/gles1/TexturedCube.cpp ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* -*- tab-width: 4; -*- */
2
+ /* vi: set sw=2 ts=4 expandtab: */
3
+
4
+ /*
5
+ * Copyright 2018-2020 Mark Callow.
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+
9
+ /**
10
+ * @file TexturedCube.cpp
11
+ * @brief Draw a textured cube.
12
+ */
13
+
14
+ #if defined(_WIN32)
15
+ #if _MSC_VER < 1900
16
+ #define snprintf _snprintf
17
+ #endif
18
+ #define _CRT_SECURE_NO_WARNINGS
19
+ #endif
20
+
21
+ #include <iomanip>
22
+ #include <sstream>
23
+ #include <ktx.h>
24
+ #include "disable_glm_warnings.h"
25
+ #include <glm/gtc/matrix_transform.hpp>
26
+ #include <glm/gtc/type_ptr.hpp>
27
+ #include "reenable_warnings.h"
28
+
29
+ #include "TexturedCube.h"
30
+ #include "cube.h"
31
+
32
+
33
+ #if defined(_WIN32)
34
+ #define snprintf _snprintf
35
+ #endif
36
+
37
+ /* ------------------------------------------------------------------------- */
38
+
39
+ LoadTestSample*
40
+ TexturedCube::create(uint32_t width, uint32_t height,
41
+ const char* const szArgs,
42
+ const std::string sBasePath)
43
+ {
44
+ return new TexturedCube(width, height, szArgs, sBasePath);
45
+ }
46
+
47
+ TexturedCube::TexturedCube(uint32_t width, uint32_t height,
48
+ const char* const szArgs,
49
+ const std::string sBasePath)
50
+ : LoadTestSample(width, height, sBasePath)
51
+ {
52
+ const GLchar* szExtensions = (const GLchar*)glGetString(GL_EXTENSIONS);
53
+ const char* filename;
54
+ std::string pathname;
55
+ GLuint gnTexture = 0;
56
+ GLenum target;
57
+ GLenum glerror;
58
+ GLboolean npotSupported, npotTexture;
59
+ ktxTexture* kTexture;
60
+ KTX_error_code ktxresult;
61
+
62
+ if (strstr(szExtensions, "OES_texture_npot") != NULL)
63
+ npotSupported = GL_TRUE;
64
+ else
65
+ npotSupported = GL_FALSE;
66
+
67
+ if ((filename = strchr(szArgs, ' ')) != NULL) {
68
+ npotTexture = GL_FALSE;
69
+ if (!strncmp(szArgs, "--npot ", 7)) {
70
+ npotTexture = GL_TRUE;
71
+ #if defined(DEBUG)
72
+ } else {
73
+ assert(0); /* Unknown argument in sampleInvocations */
74
+ #endif
75
+ }
76
+ } else {
77
+ filename = szArgs;
78
+ npotTexture = GL_FALSE;
79
+ }
80
+
81
+ if (npotTexture && !npotSupported) {
82
+ /* Load error texture. */
83
+ filename = "no-npot.ktx";
84
+ }
85
+ pathname = getAssetPath() + filename;
86
+
87
+ ktxresult = ktxTexture_CreateFromNamedFile(pathname.c_str(),
88
+ KTX_TEXTURE_CREATE_NO_FLAGS,
89
+ &kTexture);
90
+ if (KTX_SUCCESS != ktxresult) {
91
+ std::stringstream message;
92
+
93
+ message << "Creation of ktxTexture from \"" << pathname
94
+ << "\" failed: " << ktxErrorString(ktxresult);
95
+ throw std::runtime_error(message.str());
96
+ }
97
+ ktxresult = ktxTexture_GLUpload(kTexture, &gnTexture, &target, &glerror);
98
+
99
+ if (KTX_SUCCESS == ktxresult) {
100
+ if (target != GL_TEXTURE_2D) {
101
+ /* Can only draw 2D textures */
102
+ glDeleteTextures(1, &gnTexture);
103
+ return;
104
+ }
105
+ glEnable(target);
106
+
107
+ if (kTexture->numLevels > 1)
108
+ // Enable bilinear mipmapping.
109
+ // TO DO: application can consider inserting a key,value pair in
110
+ // the KTX file that indicates what type of filtering to use.
111
+ glTexParameteri(target,
112
+ GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
113
+ else
114
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
115
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
116
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
117
+
118
+ ktxTexture_Destroy(kTexture);
119
+ } else {
120
+ std::stringstream message;
121
+
122
+ message << "Load of texture from \"" << pathname << "\" failed: ";
123
+ if (ktxresult == KTX_GL_ERROR) {
124
+ message << std::showbase << "GL error " << std::hex << glerror
125
+ << "occurred.";
126
+ } else {
127
+ message << ktxErrorString(ktxresult);
128
+ }
129
+ throw std::runtime_error(message.str());
130
+ }
131
+
132
+ /* By default dithering is enabled. Dithering does not provide visual
133
+ * improvement in this sample so disable it to improve performance.
134
+ */
135
+ glDisable(GL_DITHER);
136
+
137
+ glEnable(GL_CULL_FACE);
138
+ glClearColor(0.2f,0.3f,0.4f,1.0f);
139
+
140
+ glEnableClientState(GL_VERTEX_ARRAY);
141
+ glEnableClientState(GL_COLOR_ARRAY);
142
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
143
+
144
+ glVertexPointer(3, GL_FLOAT, 0, cube_face);
145
+ glColorPointer(4, GL_FLOAT, 0, cube_color);
146
+ glTexCoordPointer(2, GL_FLOAT, 0, cube_texture);
147
+ }
148
+
149
+ TexturedCube::~TexturedCube()
150
+ {
151
+ glDisable(GL_TEXTURE_2D);
152
+ glEnable(GL_DITHER);
153
+ glDisable(GL_CULL_FACE);
154
+ glDisableClientState(GL_VERTEX_ARRAY);
155
+ glDisableClientState(GL_COLOR_ARRAY);
156
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
157
+ assert(GL_NO_ERROR == glGetError());
158
+ }
159
+
160
+ void
161
+ TexturedCube::resize(uint32_t uWidth, uint32_t uHeight)
162
+ {
163
+ glm::mat4 matProj;
164
+ glViewport(0, 0, uWidth, uHeight);
165
+
166
+ glMatrixMode( GL_PROJECTION );
167
+ matProj = glm::perspective(glm::radians(45.f),
168
+ uWidth / (float)uHeight,
169
+ 1.f, 100.f);
170
+ glLoadIdentity();
171
+ glLoadMatrixf(glm::value_ptr(matProj));
172
+
173
+ glMatrixMode( GL_MODELVIEW );
174
+ assert(GL_NO_ERROR == glGetError());
175
+ }
176
+
177
+ void
178
+ TexturedCube::run(uint32_t msTicks)
179
+ {
180
+ /* Setup the view matrix : just turn around the cube. */
181
+ const float fDistance = 5.0f;
182
+ glm::vec3 eye((float)cos( msTicks*0.001f ) * fDistance,
183
+ (float)sin( msTicks*0.0007f ) * fDistance,
184
+ (float)sin( msTicks*0.001f ) * fDistance);
185
+ glm::vec3 look(0.,0.,0.);
186
+ glm::vec3 up(0.,1.,0.);
187
+ glm::mat4 matView = glm::lookAt( eye, look, up );
188
+
189
+ glLoadIdentity();
190
+ glLoadMatrixf(glm::value_ptr(matView));
191
+
192
+ /* Draw */
193
+ glClear( GL_COLOR_BUFFER_BIT );
194
+
195
+ glDrawElements(GL_TRIANGLES, CUBE_NUM_INDICES,
196
+ GL_UNSIGNED_SHORT, cube_index_buffer);
197
+
198
+ assert(GL_NO_ERROR == glGetError());
199
+ }
200
+
201
+ /* ------------------------------------------------------------------------- */
202
+
third_party/ktx-src/tests/loadtests/glloadtests/gles1/TexturedCube.h ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* -*- tab-width: 4; -*- */
2
+ /* vi: set sw=2 ts=4 expandtab: */
3
+
4
+ /*
5
+ * Copyright 2018-2020 Mark Callow.
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+
9
+ /**
10
+ * @file TexturedCube.cpp
11
+ * @brief Draw a textured cube.
12
+ */
13
+
14
+ #ifndef TEXTURED_CUBE_H
15
+ #define TEXTURED_CUBE_H
16
+
17
+ #include <GLES/gl.h>
18
+ #include <GLES/glext.h>
19
+
20
+ #include "LoadTestSample.h"
21
+ class TexturedCube : public LoadTestSample {
22
+ public:
23
+ TexturedCube(uint32_t width, uint32_t height,
24
+ const char* const szArgs,
25
+ const std::string sBasePath);
26
+ ~TexturedCube();
27
+
28
+ virtual void resize(uint32_t width, uint32_t height);
29
+ virtual void run(uint32_t msTicks);
30
+
31
+ //virtual void getOverlayText(GLTextOverlay *textOverlay);
32
+
33
+ static LoadTestSample*
34
+ create(uint32_t width, uint32_t height,
35
+ const char* const szArgs, const std::string sBasePath);
36
+ };
37
+
38
+ #endif /* TEXTURED_CUBE_H */
third_party/ktx-src/tests/loadtests/glloadtests/resources/ios/Info.plist.in ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!--
3
+ Copyright 2015-2024 Mark Callow
4
+ SPDX-License-Identifier: Apache-2.0
5
+
6
+ WARNING: Do not attempt to edit the Info.plist you see in the Xcode
7
+ project. It is unavoidably configured from this by CMake. Edit here.
8
+ -->
9
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
10
+ <plist version="1.0">
11
+ <dict>
12
+ <key>CFBundleName</key>
13
+ <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
14
+ <key>CFBundleDisplayName</key>
15
+ <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
16
+ <key>CFBundleGetInfoString</key>
17
+ <string>${MACOSX_BUNDLE_INFO_STRING}</string>
18
+ <key>NSHumanReadableCopyright</key>
19
+ <string>${MACOSX_BUNDLE_COPYRIGHT}</string>
20
+ <key>CFBundleDevelopmentRegion</key>
21
+ <string>en</string>
22
+ <key>CFBundleExecutable</key>
23
+ <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
24
+ <key>CFBundleIdentifier</key>
25
+ <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
26
+ <key>CFBundleInfoDictionaryVersion</key>
27
+ <string>6.0</string>
28
+ <key>CFBundlePackageType</key>
29
+ <string>APPL</string>
30
+ <key>CFBundleVersion</key>
31
+ <string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
32
+ <key>CFBundleShortVersionString</key>
33
+ <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
34
+ <key>CFBundleSignature</key>
35
+ <string>????</string>
36
+ <key>NSMainNibFile</key>
37
+ <string></string>
38
+ <key>UILaunchStoryboardName</key>
39
+ <string>LaunchScreen</string>
40
+ <key>UISupportedInterfaceOrientations</key>
41
+ <array>
42
+ <string>UIInterfaceOrientationPortrait</string>
43
+ <string>UIInterfaceOrientationPortraitUpsideDown</string>
44
+ <string>UIInterfaceOrientationLandscapeLeft</string>
45
+ <string>UIInterfaceOrientationLandscapeRight</string>
46
+ </array>
47
+ <key>UIApplicationSupportsIndirectInputEvents</key>
48
+ <string>YES</string>
49
+ </dict>
50
+ </plist>