main.c 75 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051
  1. // Danil, 2021+ Vulkan shadertoy launcher, self https://github.com/danilw/vulkan-shadertoy-launcher
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. // USEFUL defines (list, use search to see what they do)
  5. // NO_RESIZE_BUF
  6. // CUSTOM_BUF_SIZE
  7. // USE_stb_image
  8. // OFFSCREEN_BUFFERS
  9. // IMAGE_TEXTURES
  10. // USE_MIPMAPS
  11. // YARIV_SHADER
  12. // USE_SCREENSHOT
  13. // buffers is VK_FORMAT_R32G32B32A32_SFLOAT
  14. // FPS_LOCK(30) hotkey function 30 FPS lock (no Vsync)
  15. // check_hotkeys function where hotkeys defined
  16. // Discard disabled, to make it work if needed change VK_C_CLEAR to VK_KEEP in this file (works in buffers)
  17. // used VK_WITHOUT_DEPTH render pass, if you need depth change to VK_WITH_DEPTH (and remember change VkClearValue clear_values adding depth and stencil clean values there)
  18. // define to not resize offscreen-buf on window resize (buffer size will be same as window on startup)
  19. // #define NO_RESIZE_BUF
  20. // if you need custom static buffer size (iResolution unique to each buffer and will be equal to this value in buffers)
  21. // #define CUSTOM_BUF_SIZE {.width = 256, .height = 256,}
  22. #if defined(VK_USE_PLATFORM_XCB_KHR)||defined(VK_USE_PLATFORM_WAYLAND_KHR)
  23. #include <unistd.h>
  24. #endif
  25. #ifdef _WIN32
  26. #pragma comment(linker, "/subsystem:windows")
  27. #endif
  28. #include <time.h>
  29. #include "../vk_utils/vk_utils.h"
  30. #include "../vk_utils/vk_render_helper.h"
  31. #include "../os_utils/utils.h"
  32. #if defined(VK_USE_PLATFORM_WAYLAND_KHR)
  33. static int resize_size[2] = {1280, 720}; // in Wayland surface should set own size
  34. #endif
  35. static bool main_image_srgb = false; // srgb surface fix
  36. // USE_stb_image comment this define to NOT use stb_image.h (compiled size will be 15Kb smaller)
  37. // USE_stb_image set in CMakeLists.txt this why it commented here, it used if you build from default cmake build
  38. // when stb_image.h not used - every image is empty(vec4(0.0)) 1x1 pixel look textures.h texture_empty
  39. //#define USE_stb_image
  40. #ifdef USE_stb_image
  41. // using stb_image
  42. #define STB_IMAGE_IMPLEMENTATION
  43. #define STBI_NO_THREAD_LOCALS
  44. #define STBI_ONLY_PNG
  45. #include "stb_image.h"
  46. #endif
  47. // numbers buffers <*.frag> files
  48. // number of buffers to create, any number(>0), if you need 0 use https://github.com/danilw/vulkan-shader-launcher
  49. // names shaders/spv/<file>.spv look files names in that folder
  50. #define OFFSCREEN_BUFFERS 4
  51. // number of images(>0)
  52. // names textures/<X>.png X start from 1
  53. #define IMAGE_TEXTURES 4
  54. // linear or mipmap for textures
  55. #define USE_MIPMAPS true
  56. // use save screenshot functions, default hotkey Z
  57. #define USE_SCREENSHOT
  58. // keyboard is texture that send from this data
  59. static bool keyboard_map[0xff][3] = {0}; //[ASCII code][0: current state of key, 1: Keypress, 2: toggle for key]
  60. static uint8_t keyboard_texture[256 * 3 * 4] = {0}; // texture
  61. static bool keyboard_need_update = false;
  62. static bool keyboard_draw = false;
  63. // update to 2021 Shadertoy iMouse.w change https://www.shadertoy.com/view/llySRh (comments)
  64. static bool last_iMousel_clicked[2] = {false, false};
  65. // do not edit, it just to see where keyboard texture used
  66. #define iKeyboard 1
  67. // to build-in compressed shaders into bin(exe) file
  68. // used OFFSCREEN_BUFFERS size, names of .hex files should be set manually(and edit yariv_shaders[]), this example using 4 buffers same as on shadertoy
  69. //#define YARIV_SHADER
  70. #ifdef YARIV_SHADER
  71. const unsigned char buf_fs_code[] = {
  72. #include "../yariv_shaders/bin/buf.frag.hex"
  73. };
  74. const unsigned char buf1_fs_code[] = {
  75. #include "../yariv_shaders/bin/buf1.frag.hex"
  76. };
  77. const unsigned char buf2_fs_code[] = {
  78. #include "../yariv_shaders/bin/buf2.frag.hex"
  79. };
  80. const unsigned char buf3_fs_code[] = {
  81. #include "../yariv_shaders/bin/buf3.frag.hex"
  82. };
  83. const unsigned char buf_vs_code[] = {
  84. #include "../yariv_shaders/bin/buf.vert.hex"
  85. };
  86. const unsigned char fs_code[] = {
  87. #include "../yariv_shaders/bin/main.frag.hex"
  88. };
  89. const unsigned char vs_code[] = {
  90. #include "../yariv_shaders/bin/main.vert.hex"
  91. };
  92. const unsigned char *yariv_shaders[] = {
  93. buf_fs_code, buf1_fs_code, buf2_fs_code, buf3_fs_code
  94. };
  95. const int yariv_shaders_size[] = {
  96. sizeof(buf_fs_code), sizeof(buf1_fs_code), sizeof(buf2_fs_code), sizeof(buf3_fs_code)
  97. };
  98. #endif
  99. struct shaders_push_constants
  100. {
  101. float iMouse[4];
  102. float iDate[4];
  103. int iMouse_lr[2];
  104. float iResolution[2];
  105. int debugdraw; // look function check_hotkeys
  106. int pCustom; //custom data
  107. float iTime;
  108. float iTimeDelta;
  109. int iFrame;
  110. };
  111. enum
  112. {
  113. BUFFER_VERTICES = 0,
  114. BUFFER_INDICES = 1,
  115. };
  116. enum
  117. {
  118. SHADER_MAIN_VERTEX = 0,
  119. SHADER_MAIN_FRAGMENT = 1,
  120. };
  121. struct render_data
  122. {
  123. struct objects
  124. {
  125. struct vertex
  126. {
  127. float pos[3];
  128. } vertices[3];
  129. uint16_t indices[3];
  130. } objects;
  131. struct shaders_push_constants push_constants;
  132. struct vk_image images[IMAGE_TEXTURES + OFFSCREEN_BUFFERS + iKeyboard];
  133. struct vk_buffer buffers[2];
  134. struct vk_shader shaders[2 + OFFSCREEN_BUFFERS * 2];
  135. struct vk_graphics_buffers *main_gbuffers;
  136. struct vk_offscreen_buffers *buf_obuffers;
  137. VkRenderPass buf_render_pass[OFFSCREEN_BUFFERS];
  138. struct vk_layout buf_layout[OFFSCREEN_BUFFERS];
  139. struct vk_pipeline buf_pipeline[OFFSCREEN_BUFFERS];
  140. VkDescriptorSet buf_desc_set[OFFSCREEN_BUFFERS];
  141. VkRenderPass main_render_pass;
  142. struct vk_layout main_layout;
  143. struct vk_pipeline main_pipeline;
  144. VkDescriptorSet main_desc_set;
  145. };
  146. struct render_data render_data = {
  147. .main_gbuffers = NULL,
  148. .buf_obuffers = NULL,
  149. };
  150. VkInstance vk;
  151. struct vk_physical_device phy_dev;
  152. struct vk_device dev;
  153. struct vk_swapchain swapchain = {0};
  154. struct app_os_window os_window;
  155. struct vk_render_essentials essentials;
  156. VkFence offscreen_fence = VK_NULL_HANDLE;
  157. VkQueue offscreen_queue[OFFSCREEN_BUFFERS] = {VK_NULL_HANDLE};
  158. VkCommandBuffer offscreen_cmd_buffer[OFFSCREEN_BUFFERS] = {VK_NULL_HANDLE};
  159. VkSemaphore wait_buf_sem = VK_NULL_HANDLE, wait_main_sem = VK_NULL_HANDLE;
  160. bool first_submission = true;
  161. bool enterFullscreen();
  162. #if defined(VK_USE_PLATFORM_WIN32_KHR)
  163. #include <shellapi.h>
  164. static HWND chWnd;
  165. static void check_hotkeys(struct app_os_window *os_window);
  166. static void update_key_map(int w, int h, bool val);
  167. static void update_keypress();
  168. static bool render_loop_draw(struct vk_physical_device *phy_dev, struct vk_device *dev, struct vk_swapchain *swapchain,
  169. struct app_os_window *os_window);
  170. static bool on_window_resize(struct vk_physical_device *phy_dev, struct vk_device *dev,
  171. struct vk_render_essentials *essentials, struct vk_swapchain *swapchain,
  172. struct render_data *render_data, struct app_os_window *os_window);
  173. #include "../os_utils/os_win_utils.h"
  174. #elif defined(VK_USE_PLATFORM_XCB_KHR)
  175. static void update_key_map(int w, int h, bool val);
  176. #include "../os_utils/xcb_x11_utils.h"
  177. #elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
  178. static void update_key_map(int w, int h, bool val);
  179. #include "../os_utils/wayland_utils.h"
  180. #endif
  181. #include "textures.h"
  182. #ifdef USE_SCREENSHOT
  183. #include "screenshot.h"
  184. #endif
  185. static void update_key_map(int w, int h, bool val)
  186. {
  187. keyboard_map[w][h] = val;
  188. keyboard_texture[(h * 256 + w) * 4] = val ? 0xff : 0x00;
  189. }
  190. static void update_keypress()
  191. {
  192. if (keyboard_need_update)
  193. keyboard_draw = true;
  194. else
  195. keyboard_draw = false;
  196. if (keyboard_need_update)
  197. {
  198. for (uint8_t i = 0; i < 0xff; i++)
  199. {
  200. update_key_map(i, 1, false);
  201. }
  202. }
  203. keyboard_need_update = false;
  204. }
  205. static bool update_iKeyboard_texture(struct vk_physical_device *phy_dev, struct vk_device *dev,
  206. struct vk_render_essentials *essentials, struct render_data *render_data)
  207. {
  208. vk_error retval = VK_ERROR_NONE;
  209. VkResult res;
  210. if (!keyboard_draw)
  211. return true;
  212. if (!essentials->first_render)
  213. {
  214. res = vkWaitForFences(dev->device, 1, &essentials->exec_fence, true, 1000000000);
  215. vk_error_set_vkresult(&retval, res);
  216. if (res)
  217. {
  218. vk_error_printf(&retval, "Wait for fence failed\n");
  219. return false;
  220. }
  221. }
  222. retval =
  223. vk_render_update_texture(phy_dev, dev, essentials, &render_data->images[IMAGE_TEXTURES + OFFSCREEN_BUFFERS],
  224. VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, keyboard_texture, "iKeyboard");
  225. if (!vk_error_is_success(&retval))
  226. return false;
  227. return true;
  228. }
  229. static bool fullscreen = false;
  230. static bool fs_once = true;
  231. static bool key_screenshot_once = true;
  232. static bool screenshot_once = false;
  233. static void check_hotkeys(struct app_os_window *os_window)
  234. {
  235. const int Key_Escape = 27, Key_Space = 32, Key_0 = 48, Key_1 = 49, Key_f = 70, Key_z = 90, Key_f11 = 122;
  236. if (keyboard_map[Key_Escape][1])
  237. os_window->app_data.quit = true;
  238. if (keyboard_map[Key_Space][1])
  239. os_window->app_data.pause = !os_window->app_data.pause;
  240. if (keyboard_map[Key_0][1])
  241. os_window->app_data.drawdebug = !os_window->app_data.drawdebug;
  242. if (keyboard_map[Key_1][1])
  243. os_window->fps_lock = !os_window->fps_lock;
  244. if (keyboard_map[Key_z][1]) {
  245. if (key_screenshot_once) { screenshot_once = true; key_screenshot_once = false; }
  246. }
  247. else key_screenshot_once = true;
  248. #if defined(VK_USE_PLATFORM_WAYLAND_KHR)
  249. //example resize event for Wayland
  250. if (keyboard_map[Key_f][1]){
  251. os_window->resize_event = true;
  252. static bool switch_res=true;
  253. if(switch_res){
  254. switch_res=false;
  255. os_window->app_data.iResolution[0]=1920;
  256. os_window->app_data.iResolution[1]=1080;
  257. }else{
  258. switch_res=true;
  259. os_window->app_data.iResolution[0]=1280;
  260. os_window->app_data.iResolution[1]=720;
  261. }
  262. }
  263. #else
  264. if (keyboard_map[Key_f][1]||keyboard_map[Key_f11][1]) {
  265. if (fs_once) { enterFullscreen(); fs_once = false; }
  266. }
  267. else fs_once = true;
  268. #endif
  269. }
  270. static vk_error allocate_render_data(struct vk_physical_device *phy_dev, struct vk_device *dev,
  271. struct vk_swapchain *swapchain, struct vk_render_essentials *essentials,
  272. struct render_data *render_data, bool reload_shaders)
  273. {
  274. static bool load_once = false;
  275. vk_error retval = VK_ERROR_NONE;
  276. VkResult res;
  277. if (!load_once)
  278. {
  279. render_data->buffers[BUFFER_VERTICES] = (struct vk_buffer){
  280. .size = sizeof render_data->objects.vertices,
  281. .usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
  282. .host_visible = false,
  283. };
  284. render_data->buffers[BUFFER_INDICES] = (struct vk_buffer){
  285. .size = sizeof render_data->objects.indices,
  286. .usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
  287. .host_visible = false,
  288. };
  289. retval = vk_create_buffers(phy_dev, dev, render_data->buffers, 2);
  290. if (!vk_error_is_success(&retval))
  291. {
  292. vk_error_printf(&retval, "Failed to create vertex, index and transformation buffers\n");
  293. return retval;
  294. }
  295. }
  296. if (!load_once)
  297. {
  298. render_data->objects = (struct objects){
  299. .vertices =
  300. {
  301. [0] =
  302. (struct vertex){
  303. .pos = {3.001, 1.001, 0.0},
  304. },
  305. [1] =
  306. (struct vertex){
  307. .pos = {-1.001, -3.001, 0.0},
  308. },
  309. [2] =
  310. (struct vertex){
  311. .pos = {-1.001, 1.001, 0.0},
  312. },
  313. },
  314. .indices =
  315. {
  316. 0,
  317. 1,
  318. 2,
  319. },
  320. };
  321. retval = vk_render_init_buffer(phy_dev, dev, essentials, &render_data->buffers[BUFFER_VERTICES],
  322. render_data->objects.vertices, "vertex");
  323. if (!vk_error_is_success(&retval))
  324. return retval;
  325. retval = vk_render_init_buffer(phy_dev, dev, essentials, &render_data->buffers[BUFFER_INDICES],
  326. render_data->objects.indices, "index");
  327. if (!vk_error_is_success(&retval))
  328. return retval;
  329. for (uint32_t i = 0; i < IMAGE_TEXTURES; i++)
  330. {
  331. char txt[255] = {0};
  332. sprintf(txt, "textures/%d.png", i + 1);
  333. #ifdef USE_stb_image
  334. retval = init_texture_file(phy_dev, dev, essentials, &render_data->images[i], txt, USE_MIPMAPS);
  335. if (!vk_error_is_success(&retval))retval = texture_empty(phy_dev, dev, essentials, &render_data->images[i], 1, 1);
  336. #else
  337. retval = texture_empty(phy_dev, dev, essentials, &render_data->images[i], 1, 1);
  338. if (!vk_error_is_success(&retval))
  339. return retval;
  340. #endif
  341. }
  342. for (uint32_t i = IMAGE_TEXTURES; i < IMAGE_TEXTURES + OFFSCREEN_BUFFERS; i++)
  343. {
  344. retval = texture_empty(phy_dev, dev, essentials, &render_data->images[i], 1, 1);
  345. if (!vk_error_is_success(&retval))
  346. return retval;
  347. }
  348. retval = texture_empty(phy_dev, dev, essentials, &render_data->images[IMAGE_TEXTURES + OFFSCREEN_BUFFERS], 256,
  349. 3); // iKeyboard
  350. if (!vk_error_is_success(&retval))
  351. return retval;
  352. }
  353. if ((!load_once) || (reload_shaders))
  354. {
  355. render_data->shaders[SHADER_MAIN_VERTEX] = (struct vk_shader){
  356. .spirv_file = "shaders/spv/main.vert.spv",
  357. .stage = VK_SHADER_STAGE_VERTEX_BIT,
  358. };
  359. render_data->shaders[SHADER_MAIN_FRAGMENT] = (struct vk_shader){
  360. .spirv_file = "shaders/spv/main.frag.spv",
  361. .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
  362. };
  363. char txt[OFFSCREEN_BUFFERS][255] = {0};
  364. for (uint32_t i = 0; i < OFFSCREEN_BUFFERS * 2; i += 2)
  365. {
  366. render_data->shaders[i + 2] = (struct vk_shader){
  367. .spirv_file = "shaders/spv/buf.vert.spv",
  368. .stage = VK_SHADER_STAGE_VERTEX_BIT,
  369. };
  370. if (i > 0)
  371. {
  372. sprintf(txt[i / 2], "shaders/spv/buf%d.frag.spv", i / 2);
  373. }
  374. else
  375. {
  376. sprintf(txt[i / 2], "shaders/spv/buf.frag.spv");
  377. }
  378. render_data->shaders[i + 2 + 1] = (struct vk_shader){
  379. .spirv_file = txt[i / 2],
  380. .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
  381. };
  382. }
  383. #ifdef YARIV_SHADER
  384. retval = vk_load_shader_yariv(dev, (const uint32_t *)vs_code, &render_data->shaders[SHADER_MAIN_VERTEX].shader,
  385. sizeof(vs_code));
  386. if (!vk_error_is_success(&retval))
  387. {
  388. vk_error_printf(&retval, "Could not load the shaders\n");
  389. return retval;
  390. }
  391. retval = vk_load_shader_yariv(dev, (const uint32_t *)fs_code,
  392. &render_data->shaders[SHADER_MAIN_FRAGMENT].shader, sizeof(fs_code));
  393. if (!vk_error_is_success(&retval))
  394. {
  395. vk_error_printf(&retval, "Could not load the shaders\n");
  396. return retval;
  397. }
  398. for (uint32_t i = 0; i < OFFSCREEN_BUFFERS * 2; i += 2)
  399. {
  400. retval = vk_load_shader_yariv(dev, (const uint32_t *)buf_vs_code,
  401. &render_data->shaders[i + 2].shader, sizeof(buf_vs_code));
  402. if (!vk_error_is_success(&retval))
  403. {
  404. vk_error_printf(&retval, "Could not load the shaders\n");
  405. return retval;
  406. }
  407. retval = vk_load_shader_yariv(dev, (const uint32_t *)(yariv_shaders[i/2]),
  408. &render_data->shaders[i + 2 + 1].shader, yariv_shaders_size[i/2]);
  409. if (!vk_error_is_success(&retval))
  410. {
  411. vk_error_printf(&retval, "Could not load the shaders\n");
  412. return retval;
  413. }
  414. }
  415. #else
  416. retval = vk_load_shaders(dev, render_data->shaders, 2 + OFFSCREEN_BUFFERS * 2);
  417. if (!vk_error_is_success(&retval))
  418. {
  419. vk_error_printf(&retval, "Could not load the shaders\n");
  420. return retval;
  421. }
  422. #endif
  423. }
  424. struct VkExtent2D init_size;
  425. #if defined(VK_USE_PLATFORM_WAYLAND_KHR)
  426. init_size.width = resize_size[0];
  427. init_size.height = resize_size[1];
  428. #else
  429. init_size.width = swapchain->surface_caps.currentExtent.width;
  430. init_size.height = swapchain->surface_caps.currentExtent.height;
  431. #endif
  432. render_data->main_gbuffers = malloc(essentials->image_count * sizeof *render_data->main_gbuffers);
  433. for (uint32_t i = 0; i < essentials->image_count; ++i)
  434. render_data->main_gbuffers[i] = (struct vk_graphics_buffers){
  435. .surface_size = init_size,
  436. .swapchain_image = essentials->images[i],
  437. };
  438. #ifdef NO_RESIZE_BUF
  439. if (!load_once)
  440. {
  441. #endif
  442. render_data->buf_obuffers = malloc(2 * (sizeof(*render_data->buf_obuffers)) * OFFSCREEN_BUFFERS);
  443. for (uint32_t i = 0; i < 2 * OFFSCREEN_BUFFERS; i++)
  444. render_data->buf_obuffers[i] = (struct vk_offscreen_buffers)
  445. {
  446. #if defined(CUSTOM_BUF_SIZE) && defined(NO_RESIZE_BUF)
  447. .surface_size = (struct VkExtent2D)CUSTOM_BUF_SIZE,
  448. #else
  449. .surface_size = init_size,
  450. #endif
  451. };
  452. #ifdef NO_RESIZE_BUF
  453. }
  454. #endif
  455. // 8bit BGRA for main_image VK_FORMAT_B8G8R8A8_UNORM
  456. if(swapchain->surface_format.format!=VK_FORMAT_B8G8R8A8_UNORM)main_image_srgb=true;
  457. retval = vk_create_graphics_buffers(phy_dev, dev, swapchain->surface_format.format, render_data->main_gbuffers,
  458. essentials->image_count, &render_data->main_render_pass, VK_C_CLEAR,
  459. VK_WITHOUT_DEPTH);
  460. if (!vk_error_is_success(&retval))
  461. {
  462. vk_error_printf(&retval, "Could not create graphics buffers\n");
  463. return retval;
  464. }
  465. #ifdef NO_RESIZE_BUF
  466. if (!load_once)
  467. {
  468. #endif
  469. for (uint32_t i = 0; i < OFFSCREEN_BUFFERS; i++)
  470. {
  471. // 32 bit format RGBA for buffers VK_FORMAT_R32G32B32A32_SFLOAT
  472. retval = vk_create_offscreen_buffers(phy_dev, dev, VK_FORMAT_R32G32B32A32_SFLOAT,
  473. &render_data->buf_obuffers[i * 2], 2, &render_data->buf_render_pass[i],
  474. VK_C_CLEAR, VK_WITHOUT_DEPTH, true);
  475. if (!vk_error_is_success(&retval))
  476. {
  477. vk_error_printf(&retval, "Could not create off-screen buffers\n");
  478. return retval;
  479. }
  480. }
  481. #ifdef NO_RESIZE_BUF
  482. }
  483. #endif
  484. struct vk_image **image_pointer; //&render_data->buf_obuffers[2].color
  485. image_pointer = malloc(1 * sizeof(struct vk_image *) * (IMAGE_TEXTURES + OFFSCREEN_BUFFERS + iKeyboard));
  486. for (uint32_t i = 0; i < IMAGE_TEXTURES + OFFSCREEN_BUFFERS + iKeyboard; i++)
  487. {
  488. image_pointer[i] = &render_data->images[i];
  489. }
  490. VkPushConstantRange push_constant_range = {
  491. .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
  492. .offset = 0,
  493. .size = sizeof render_data->push_constants,
  494. };
  495. /*******************
  496. * BUF PART *
  497. *******************/
  498. #ifdef NO_RESIZE_BUF
  499. if (!load_once)
  500. {
  501. #endif
  502. for (int i = 0; i < OFFSCREEN_BUFFERS; i++)
  503. {
  504. /* Layouts */
  505. struct vk_resources resources = {
  506. .images = *image_pointer,
  507. .image_count = IMAGE_TEXTURES + OFFSCREEN_BUFFERS + iKeyboard,
  508. .buffers = render_data->buffers,
  509. .buffer_count = 2,
  510. .shaders = &render_data->shaders[SHADER_MAIN_FRAGMENT + 1 + i * 2],
  511. .shader_count = 2,
  512. .push_constants = &push_constant_range,
  513. .push_constant_count = 1,
  514. .render_pass = render_data->buf_render_pass[i],
  515. };
  516. render_data->buf_layout[i] = (struct vk_layout){
  517. .resources = &resources,
  518. };
  519. uint32_t img_patern[3] = {IMAGE_TEXTURES, OFFSCREEN_BUFFERS, iKeyboard};
  520. retval = vk_make_graphics_layouts(dev, &render_data->buf_layout[i], 1, true, img_patern, 3);
  521. if (!vk_error_is_success(&retval))
  522. {
  523. vk_error_printf(&retval, "BUF: Could not create descriptor set or pipeline layouts\n");
  524. return retval;
  525. }
  526. /* Pipeline */
  527. VkVertexInputBindingDescription vertex_binding = {
  528. .binding = 0,
  529. .stride = sizeof *render_data->objects.vertices,
  530. .inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
  531. };
  532. VkVertexInputAttributeDescription vertex_attributes[1] = {
  533. [0] =
  534. {
  535. .location = 0,
  536. .binding = 0,
  537. .format = VK_FORMAT_R32G32B32_SFLOAT,
  538. .offset = 0,
  539. },
  540. };
  541. render_data->buf_pipeline[i] = (struct vk_pipeline){
  542. .layout = &render_data->buf_layout[i],
  543. .vertex_input_state =
  544. {
  545. .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
  546. .vertexBindingDescriptionCount = 1,
  547. .pVertexBindingDescriptions = &vertex_binding,
  548. .vertexAttributeDescriptionCount = 1,
  549. .pVertexAttributeDescriptions = vertex_attributes,
  550. },
  551. .input_assembly_state =
  552. {
  553. .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
  554. .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
  555. },
  556. .tessellation_state =
  557. {
  558. .sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,
  559. },
  560. .thread_count = 1,
  561. };
  562. retval = vk_make_graphics_pipelines(dev, &render_data->buf_pipeline[i], 1, false);
  563. if (!vk_error_is_success(&retval))
  564. {
  565. vk_error_printf(&retval, "BUF: Could not create graphics pipeline\n");
  566. return retval;
  567. }
  568. /* Descriptor Set */
  569. VkDescriptorSetAllocateInfo set_info = {
  570. .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
  571. .descriptorPool = render_data->buf_pipeline[i].set_pool,
  572. .descriptorSetCount = 1,
  573. .pSetLayouts = &render_data->buf_layout[i].set_layout,
  574. };
  575. res = vkAllocateDescriptorSets(dev->device, &set_info, &render_data->buf_desc_set[i]);
  576. retval = VK_ERROR_NONE;
  577. vk_error_set_vkresult(&retval, res);
  578. if (res)
  579. {
  580. vk_error_printf(&retval, "BUF: Could not allocate descriptor set from pool\n");
  581. return retval;
  582. }
  583. }
  584. #ifdef NO_RESIZE_BUF
  585. }
  586. #endif
  587. /*******************
  588. * MAIN_IMAGE PART *
  589. *******************/
  590. {
  591. /* Layouts */
  592. struct vk_resources resources = {
  593. .images = *image_pointer,
  594. .image_count = IMAGE_TEXTURES + OFFSCREEN_BUFFERS + iKeyboard,
  595. .buffers = render_data->buffers,
  596. .buffer_count = 2,
  597. .shaders = &render_data->shaders[SHADER_MAIN_VERTEX],
  598. .shader_count = 2,
  599. .push_constants = &push_constant_range,
  600. .push_constant_count = 1,
  601. .render_pass = render_data->main_render_pass,
  602. };
  603. render_data->main_layout = (struct vk_layout){
  604. .resources = &resources,
  605. };
  606. uint32_t img_patern[3] = {IMAGE_TEXTURES, OFFSCREEN_BUFFERS, iKeyboard};
  607. retval = vk_make_graphics_layouts(dev, &render_data->main_layout, 1, true, img_patern, 3);
  608. if (!vk_error_is_success(&retval))
  609. {
  610. vk_error_printf(&retval, "Could not create descriptor set or pipeline layouts\n");
  611. return retval;
  612. }
  613. /* Pipeline */
  614. VkVertexInputBindingDescription vertex_binding = {
  615. .binding = 0,
  616. .stride = sizeof *render_data->objects.vertices,
  617. .inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
  618. };
  619. VkVertexInputAttributeDescription vertex_attributes[1] = {
  620. [0] =
  621. {
  622. .location = 0,
  623. .binding = 0,
  624. .format = VK_FORMAT_R32G32B32_SFLOAT,
  625. .offset = 0,
  626. },
  627. };
  628. render_data->main_pipeline = (struct vk_pipeline){
  629. .layout = &render_data->main_layout,
  630. .vertex_input_state =
  631. {
  632. .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
  633. .vertexBindingDescriptionCount = 1,
  634. .pVertexBindingDescriptions = &vertex_binding,
  635. .vertexAttributeDescriptionCount = 1,
  636. .pVertexAttributeDescriptions = vertex_attributes,
  637. },
  638. .input_assembly_state =
  639. {
  640. .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
  641. .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
  642. },
  643. .tessellation_state =
  644. {
  645. .sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,
  646. },
  647. .thread_count = 1,
  648. };
  649. retval = vk_make_graphics_pipelines(dev, &render_data->main_pipeline, 1, false);
  650. if (!vk_error_is_success(&retval))
  651. {
  652. vk_error_printf(&retval, "Could not create graphics pipeline\n");
  653. return retval;
  654. }
  655. /* Descriptor Set */
  656. VkDescriptorSetAllocateInfo set_info = {
  657. .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
  658. .descriptorPool = render_data->main_pipeline.set_pool,
  659. .descriptorSetCount = 1,
  660. .pSetLayouts = &render_data->main_layout.set_layout,
  661. };
  662. res = vkAllocateDescriptorSets(dev->device, &set_info, &render_data->main_desc_set);
  663. retval = VK_ERROR_NONE;
  664. vk_error_set_vkresult(&retval, res);
  665. if (res)
  666. {
  667. vk_error_printf(&retval, "Could not allocate descriptor set from pool\n");
  668. return retval;
  669. }
  670. }
  671. load_once = true;
  672. free(image_pointer);
  673. return retval;
  674. }
  675. static void free_render_data(struct vk_device *dev, struct vk_render_essentials *essentials,
  676. struct render_data *render_data)
  677. {
  678. vkDeviceWaitIdle(dev->device);
  679. vk_free_pipelines(dev, &render_data->main_pipeline, 1);
  680. vk_free_layouts(dev, &render_data->main_layout, 1);
  681. vk_free_pipelines(dev, render_data->buf_pipeline, OFFSCREEN_BUFFERS);
  682. vk_free_layouts(dev, render_data->buf_layout, OFFSCREEN_BUFFERS);
  683. vk_free_images(dev, render_data->images, IMAGE_TEXTURES + OFFSCREEN_BUFFERS + iKeyboard);
  684. vk_free_buffers(dev, render_data->buffers, 2);
  685. vk_free_shaders(dev, render_data->shaders, 2 + OFFSCREEN_BUFFERS * 2);
  686. for (int i = 0; i < OFFSCREEN_BUFFERS; i++)
  687. {
  688. vk_free_offscreen_buffers(dev, &render_data->buf_obuffers[i * 2], 2, render_data->buf_render_pass[i]);
  689. }
  690. vk_free_graphics_buffers(dev, render_data->main_gbuffers, essentials->image_count, render_data->main_render_pass);
  691. free(render_data->main_gbuffers);
  692. free(render_data->buf_obuffers);
  693. }
  694. // TO DO FREE BZUF FENCE LOOP
  695. static void exit_cleanup_render_loop(struct vk_device *dev, struct vk_render_essentials *essentials,
  696. struct render_data *render_data, VkSemaphore wait_buf_sem,
  697. VkSemaphore wait_main_sem, VkFence offscreen_fence)
  698. {
  699. vkDeviceWaitIdle(dev->device);
  700. if (offscreen_fence != VK_NULL_HANDLE)
  701. vkDestroyFence(dev->device, offscreen_fence, NULL);
  702. if (wait_main_sem != VK_NULL_HANDLE)
  703. vkDestroySemaphore(dev->device, wait_main_sem, NULL);
  704. if (wait_buf_sem != VK_NULL_HANDLE)
  705. vkDestroySemaphore(dev->device, wait_buf_sem, NULL);
  706. free_render_data(dev, essentials, render_data);
  707. vk_render_cleanup_essentials(essentials, dev);
  708. }
  709. static void render_loop_init(struct vk_physical_device *phy_dev, struct vk_device *dev, struct vk_swapchain *swapchain,
  710. struct app_os_window *os_window)
  711. {
  712. int res;
  713. vk_error retval = VK_ERROR_NONE;
  714. static bool once = false;
  715. res = vk_render_get_essentials(&essentials, phy_dev, dev, swapchain);
  716. if (res)
  717. {
  718. vk_render_cleanup_essentials(&essentials, dev);
  719. return;
  720. }
  721. if (!once)
  722. {
  723. uint32_t *presentable_queues = NULL;
  724. uint32_t presentable_queue_count = 0;
  725. retval =
  726. vk_get_presentable_queues(phy_dev, dev, swapchain->surface, &presentable_queues, &presentable_queue_count);
  727. if (!vk_error_is_success(&retval) || presentable_queue_count == 0)
  728. {
  729. printf(
  730. "No presentable queue families. You should have got this error in vk_render_get_essentials before.\n");
  731. free(presentable_queues);
  732. vk_render_cleanup_essentials(&essentials, dev);
  733. return;
  734. }
  735. for (uint32_t i = 0; i < OFFSCREEN_BUFFERS; i++)
  736. {
  737. offscreen_queue[i] =
  738. dev->command_pools[presentable_queues[0]].queues[0]; // used only one presentable queue always
  739. offscreen_cmd_buffer[i] = dev->command_pools[presentable_queues[0]].buffers[1 + i];
  740. }
  741. free(presentable_queues);
  742. }
  743. retval =
  744. allocate_render_data(phy_dev, dev, swapchain, &essentials, &render_data, os_window->reload_shaders_on_resize);
  745. if (!vk_error_is_success(&retval))
  746. {
  747. free_render_data(dev, &essentials, &render_data);
  748. vk_render_cleanup_essentials(&essentials, dev);
  749. return;
  750. }
  751. #ifdef NO_RESIZE_BUF
  752. if (!once)
  753. {
  754. #endif
  755. for (int i = 0; i < OFFSCREEN_BUFFERS * 2; i++)
  756. {
  757. retval = vk_render_transition_images(dev, &essentials, &render_data.buf_obuffers[i].color, 1,
  758. VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
  759. VK_IMAGE_ASPECT_COLOR_BIT, "off-screen color");
  760. if (!vk_error_is_success(&retval))
  761. {
  762. free_render_data(dev, &essentials, &render_data);
  763. vk_render_cleanup_essentials(&essentials, dev);
  764. return;
  765. }
  766. }
  767. #ifdef NO_RESIZE_BUF
  768. }
  769. #endif
  770. if (!once)
  771. {
  772. VkSemaphoreCreateInfo sem_info = {
  773. .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
  774. };
  775. res = vkCreateSemaphore(dev->device, &sem_info, NULL, &wait_buf_sem);
  776. vk_error_set_vkresult(&retval, res);
  777. if (res)
  778. {
  779. vk_error_printf(&retval, "Failed to create wait-render semaphore\n");
  780. exit_cleanup_render_loop(dev, &essentials, &render_data, wait_buf_sem, wait_main_sem, offscreen_fence);
  781. return;
  782. }
  783. res = vkCreateSemaphore(dev->device, &sem_info, NULL, &wait_main_sem);
  784. vk_error_set_vkresult(&retval, res);
  785. if (res)
  786. {
  787. vk_error_printf(&retval, "Failed to create wait-post-process semaphore\n");
  788. exit_cleanup_render_loop(dev, &essentials, &render_data, wait_buf_sem, wait_main_sem, offscreen_fence);
  789. return;
  790. }
  791. VkFenceCreateInfo fence_info = {
  792. .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
  793. };
  794. res = vkCreateFence(dev->device, &fence_info, NULL, &offscreen_fence);
  795. vk_error_set_vkresult(&retval, res);
  796. if (res)
  797. {
  798. vk_error_printf(&retval, "Failed to create fence\n");
  799. exit_cleanup_render_loop(dev, &essentials, &render_data, wait_buf_sem, wait_main_sem, offscreen_fence);
  800. return;
  801. }
  802. }
  803. once = true;
  804. os_window->prepared = true;
  805. os_window->resize_event = false;
  806. return;
  807. }
  808. static void exit_cleanup(VkInstance vk, struct vk_device *dev, struct vk_swapchain *swapchain,
  809. struct app_os_window *os_window)
  810. {
  811. if(swapchain)vk_free_swapchain(vk, dev, swapchain);
  812. if(dev)vk_cleanup(dev);
  813. #if defined(VK_USE_PLATFORM_XCB_KHR)
  814. xcb_destroy_window(os_window->connection, os_window->xcb_window);
  815. xcb_disconnect(os_window->connection);
  816. free(os_window->atom_wm_delete_window);
  817. #elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
  818. xdg_toplevel_destroy(os_window->xdg_toplevel);
  819. xdg_surface_destroy(os_window->xdg_surface);
  820. wl_keyboard_destroy(os_window->keyboard);
  821. wl_pointer_destroy(os_window->pointer);
  822. wl_seat_destroy(os_window->seat);
  823. wl_surface_destroy(os_window->surface);
  824. xdg_wm_base_destroy(os_window->shell);
  825. wl_compositor_destroy(os_window->compositor);
  826. wl_registry_destroy(os_window->registry);
  827. wl_display_disconnect(os_window->display);
  828. #endif
  829. vk_exit(vk);
  830. }
  831. static bool on_window_resize(struct vk_physical_device *phy_dev, struct vk_device *dev,
  832. struct vk_render_essentials *essentials, struct vk_swapchain *swapchain,
  833. struct render_data *render_data, struct app_os_window *os_window)
  834. {
  835. vk_error res = VK_ERROR_NONE;
  836. if (!os_window->prepared)
  837. return true;
  838. vkDeviceWaitIdle(dev->device);
  839. os_window->prepared = false;
  840. #if defined(VK_USE_PLATFORM_WAYLAND_KHR)
  841. resize_size[0] = os_window->app_data.iResolution[0];
  842. resize_size[1] = os_window->app_data.iResolution[1];
  843. #endif
  844. vk_free_pipelines(dev, &render_data->main_pipeline, 1);
  845. vk_free_graphics_buffers(dev, render_data->main_gbuffers, essentials->image_count, render_data->main_render_pass);
  846. vk_free_layouts(dev, &render_data->main_layout, 1);
  847. #ifndef NO_RESIZE_BUF
  848. vk_free_pipelines(dev, render_data->buf_pipeline, OFFSCREEN_BUFFERS);
  849. for (int i = 0; i < OFFSCREEN_BUFFERS; i++)
  850. {
  851. vk_free_offscreen_buffers(dev, &render_data->buf_obuffers[i * 2], 2, render_data->buf_render_pass[i]);
  852. }
  853. vk_free_layouts(dev, render_data->buf_layout, OFFSCREEN_BUFFERS);
  854. #endif
  855. if (os_window->reload_shaders_on_resize)
  856. vk_free_shaders(dev, render_data->shaders, 2 + OFFSCREEN_BUFFERS * 2);
  857. vk_render_cleanup_essentials(essentials, dev);
  858. free(render_data->main_gbuffers);
  859. #ifndef NO_RESIZE_BUF
  860. free(render_data->buf_obuffers);
  861. #endif
  862. res = vk_get_swapchain(vk, phy_dev, dev, swapchain, os_window, 1, &os_window->present_mode);
  863. if (vk_error_is_error(&res))
  864. {
  865. vk_error_printf(&res, "Could not create surface and swapchain\n");
  866. exit_cleanup(vk, dev, swapchain, os_window);
  867. return false;
  868. }
  869. render_loop_init(phy_dev, dev, swapchain, os_window);
  870. return true;
  871. }
  872. void update_params(struct app_data_struct *app_data, bool fps_lock)
  873. {
  874. float rdelta = 0;
  875. if (fps_lock)
  876. FPS_LOCK(30);
  877. float delta = update_fps_delta();
  878. if (!app_data->pause)
  879. {
  880. app_data->iTime += delta;
  881. }
  882. app_data->iFrame++;
  883. app_data->iTimeDelta = delta;
  884. float pause_time = pres_pause(app_data->pause);
  885. }
  886. void set_push_constants(struct app_os_window *os_window)
  887. {
  888. struct my_time_struct my_time;
  889. get_local_time(&my_time);
  890. float day_sec = ((float)my_time.msec) / 1000.0 + my_time.sec + my_time.min * 60 + my_time.hour * 3600;
  891. last_iMousel_clicked[0] = last_iMousel_clicked[1];
  892. last_iMousel_clicked[1] = os_window->app_data.iMouse_click[0];
  893. render_data.push_constants = (struct shaders_push_constants){
  894. .iResolution[0] = os_window->app_data.iResolution[0],
  895. .iResolution[1] = os_window->app_data.iResolution[1],
  896. .iTime = os_window->app_data.iTime,
  897. .iTimeDelta = os_window->app_data.iTimeDelta,
  898. .iFrame = os_window->app_data.iFrame,
  899. .iMouse[0] = os_window->app_data.iMouse[0],
  900. .iMouse[1] = os_window->app_data.iMouse[1],
  901. .iMouse[2] = os_window->app_data.iMouse_lclick[0],
  902. .iMouse[3] = (last_iMousel_clicked[0]) ? -abs(os_window->app_data.iMouse_lclick[1])
  903. : os_window->app_data.iMouse_lclick[1],
  904. .iMouse_lr[0] = (int)os_window->app_data.iMouse_click[0],
  905. .iMouse_lr[1] = (int)os_window->app_data.iMouse_click[1],
  906. .iDate[0] = my_time.year,
  907. .iDate[1] = my_time.month,
  908. .iDate[2] = my_time.day,
  909. .iDate[3] = day_sec,
  910. .debugdraw = (int)os_window->app_data.drawdebug,
  911. .pCustom=(os_window->app_data.pause?1:0)+(main_image_srgb?10:0),
  912. };
  913. }
  914. void update_push_constants_window_size(struct app_os_window *os_window)
  915. {
  916. render_data.push_constants.iMouse[0] = os_window->app_data.iMouse[0];
  917. render_data.push_constants.iMouse[1] = os_window->app_data.iMouse[1];
  918. render_data.push_constants.iMouse[2] = os_window->app_data.iMouse_lclick[0];
  919. render_data.push_constants.iMouse[3] =
  920. (last_iMousel_clicked[0]) ? -abs(os_window->app_data.iMouse_lclick[1]) : os_window->app_data.iMouse_lclick[1],
  921. render_data.push_constants.iResolution[0] = os_window->app_data.iResolution[0];
  922. render_data.push_constants.iResolution[1] = os_window->app_data.iResolution[1];
  923. }
  924. #define sign(x) ((x > 0) ? 1 : ((x < 0) ? -1 : 0))
  925. void update_push_constants_local_size(float width, float height)
  926. {
  927. render_data.push_constants.iMouse[0] =
  928. ((render_data.push_constants.iMouse[0] / render_data.push_constants.iResolution[1]) -
  929. 0.5 * (render_data.push_constants.iResolution[0] / render_data.push_constants.iResolution[1])) *
  930. height +
  931. 0.5 * width;
  932. render_data.push_constants.iMouse[1] =
  933. ((render_data.push_constants.iMouse[1] / render_data.push_constants.iResolution[1]) - 0.5) * height +
  934. 0.5 * height;
  935. render_data.push_constants.iMouse[2] =
  936. sign(render_data.push_constants.iMouse[2]) *
  937. (((fabs(render_data.push_constants.iMouse[2]) / render_data.push_constants.iResolution[1]) -
  938. 0.5 * (render_data.push_constants.iResolution[0] / render_data.push_constants.iResolution[1])) *
  939. height +
  940. 0.5 * width);
  941. render_data.push_constants.iMouse[3] =
  942. sign(render_data.push_constants.iMouse[3]) *
  943. (((fabs(render_data.push_constants.iMouse[3]) / render_data.push_constants.iResolution[1]) - 0.5) * height +
  944. 0.5 * height);
  945. render_data.push_constants.iResolution[0] = width;
  946. render_data.push_constants.iResolution[1] = height;
  947. }
  948. static bool render_loop_buf(struct vk_physical_device *phy_dev, struct vk_device *dev,
  949. struct vk_render_essentials *essentials, struct render_data *render_data,
  950. VkCommandBuffer cmd_buffer, int render_index, int buffer_index,
  951. struct app_data_struct *app_data)
  952. {
  953. vk_error retval = VK_ERROR_NONE;
  954. VkResult res;
  955. if ((!essentials->first_render) && (buffer_index == 0))
  956. {
  957. res = vkWaitForFences(dev->device, 1, &essentials->exec_fence, true, 1000000000);
  958. vk_error_set_vkresult(&retval, res);
  959. if (res)
  960. {
  961. vk_error_printf(&retval, "Wait for fence failed\n");
  962. return false;
  963. }
  964. }
  965. #ifdef NO_RESIZE_BUF
  966. update_push_constants_local_size(render_data->buf_obuffers[render_index + buffer_index * 2].surface_size.width,
  967. render_data->buf_obuffers[render_index + buffer_index * 2].surface_size.height);
  968. #endif
  969. vkResetCommandBuffer(cmd_buffer, 0);
  970. VkCommandBufferBeginInfo begin_info = {
  971. .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
  972. };
  973. res = vkBeginCommandBuffer(cmd_buffer, &begin_info);
  974. vk_error_set_vkresult(&retval, res);
  975. if (res)
  976. {
  977. vk_error_printf(&retval, "BUF: Couldn't even begin recording a command buffer\n");
  978. return false;
  979. };
  980. VkImageMemoryBarrier image_barrier = {
  981. .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
  982. .srcAccessMask = VK_ACCESS_MEMORY_READ_BIT,
  983. .dstAccessMask = VK_ACCESS_MEMORY_WRITE_BIT,
  984. .oldLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
  985. .newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
  986. .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
  987. .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
  988. .image = render_data->buf_obuffers[render_index + buffer_index * 2].color.image,
  989. .subresourceRange =
  990. {
  991. .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
  992. .baseMipLevel = 0,
  993. .levelCount = 1,
  994. .baseArrayLayer = 0,
  995. .layerCount = 1,
  996. },
  997. };
  998. vkCmdPipelineBarrier(cmd_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, 0, 0, NULL,
  999. 0, NULL, 1, &image_barrier);
  1000. VkClearValue clear_values = {
  1001. .color =
  1002. {
  1003. .float32 = {0.0, 0.0, 0.0, 0.0},
  1004. },
  1005. };
  1006. VkRenderPassBeginInfo pass_info = {
  1007. .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
  1008. .renderPass = render_data->buf_render_pass[buffer_index],
  1009. .framebuffer = render_data->buf_obuffers[render_index + buffer_index * 2].framebuffer,
  1010. .renderArea =
  1011. {
  1012. .offset =
  1013. {
  1014. .x = 0,
  1015. .y = 0,
  1016. },
  1017. .extent = render_data->buf_obuffers[render_index + buffer_index * 2].surface_size,
  1018. },
  1019. .clearValueCount = 1,
  1020. .pClearValues = &clear_values,
  1021. };
  1022. vkCmdBeginRenderPass(cmd_buffer, &pass_info, VK_SUBPASS_CONTENTS_INLINE);
  1023. vkCmdBindPipeline(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, render_data->buf_pipeline[buffer_index].pipeline);
  1024. int render_index_t[OFFSCREEN_BUFFERS];
  1025. for (int i = 0; i < OFFSCREEN_BUFFERS; i++)
  1026. {
  1027. if (i < buffer_index)
  1028. {
  1029. render_index_t[i] = render_index + i * 2;
  1030. }
  1031. else
  1032. {
  1033. render_index_t[i] = render_index - 1 + i * 2;
  1034. if (render_index_t[i] < i * 2)
  1035. render_index_t[i] = 1 + i * 2;
  1036. }
  1037. }
  1038. VkDescriptorImageInfo set_write_image_info[IMAGE_TEXTURES + OFFSCREEN_BUFFERS + iKeyboard] = {0};
  1039. for (uint32_t i = 0; i < IMAGE_TEXTURES; i++)
  1040. {
  1041. set_write_image_info[i] = (VkDescriptorImageInfo){
  1042. .sampler = render_data->images[i].sampler,
  1043. .imageView = render_data->images[i].view,
  1044. .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
  1045. };
  1046. }
  1047. for (uint32_t i = 0; i < OFFSCREEN_BUFFERS; i++)
  1048. {
  1049. set_write_image_info[IMAGE_TEXTURES + i] = (VkDescriptorImageInfo){
  1050. .sampler = render_data->buf_obuffers[render_index_t[i]].color.sampler,
  1051. .imageView = render_data->buf_obuffers[render_index_t[i]].color.view,
  1052. .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
  1053. };
  1054. }
  1055. set_write_image_info[IMAGE_TEXTURES + OFFSCREEN_BUFFERS] = (VkDescriptorImageInfo){
  1056. .sampler = render_data->images[IMAGE_TEXTURES + OFFSCREEN_BUFFERS].sampler,
  1057. .imageView = render_data->images[IMAGE_TEXTURES + OFFSCREEN_BUFFERS].view,
  1058. .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
  1059. };
  1060. VkWriteDescriptorSet set_write[3] = {
  1061. [0] =
  1062. {
  1063. .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
  1064. .dstSet = render_data->buf_desc_set[buffer_index],
  1065. .dstBinding = 0,
  1066. .descriptorCount = IMAGE_TEXTURES,
  1067. .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
  1068. .pImageInfo = &set_write_image_info[0],
  1069. },
  1070. [1] =
  1071. {
  1072. .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
  1073. .dstSet = render_data->buf_desc_set[buffer_index],
  1074. .dstBinding = IMAGE_TEXTURES,
  1075. .descriptorCount = OFFSCREEN_BUFFERS,
  1076. .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
  1077. .pImageInfo = &set_write_image_info[IMAGE_TEXTURES],
  1078. },
  1079. [2] =
  1080. {
  1081. .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
  1082. .dstSet = render_data->buf_desc_set[buffer_index],
  1083. .dstBinding = IMAGE_TEXTURES + OFFSCREEN_BUFFERS,
  1084. .descriptorCount = iKeyboard,
  1085. .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
  1086. .pImageInfo = &set_write_image_info[IMAGE_TEXTURES + OFFSCREEN_BUFFERS],
  1087. },
  1088. };
  1089. vkUpdateDescriptorSets(dev->device, 3, set_write, 0, NULL);
  1090. vkCmdBindDescriptorSets(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
  1091. render_data->buf_layout[buffer_index].pipeline_layout, 0, 1,
  1092. &render_data->buf_desc_set[buffer_index], 0, NULL);
  1093. VkDeviceSize vertices_offset = 0;
  1094. vkCmdBindVertexBuffers(cmd_buffer, 0, 1, &render_data->buffers[BUFFER_VERTICES].buffer, &vertices_offset);
  1095. vkCmdBindIndexBuffer(cmd_buffer, render_data->buffers[BUFFER_INDICES].buffer, 0, VK_INDEX_TYPE_UINT16);
  1096. VkViewport viewport = {
  1097. .x = 0,
  1098. .y = 0,
  1099. .width = render_data->buf_obuffers[render_index + buffer_index * 2].surface_size.width,
  1100. .height = render_data->buf_obuffers[render_index + buffer_index * 2].surface_size.height,
  1101. .minDepth = 0,
  1102. .maxDepth = 1,
  1103. };
  1104. vkCmdSetViewport(cmd_buffer, 0, 1, &viewport);
  1105. VkRect2D scissor = {
  1106. .offset =
  1107. {
  1108. .x = 0,
  1109. .y = 0,
  1110. },
  1111. .extent = render_data->buf_obuffers[render_index + buffer_index * 2].surface_size,
  1112. };
  1113. vkCmdSetScissor(cmd_buffer, 0, 1, &scissor);
  1114. vkCmdPushConstants(cmd_buffer, render_data->buf_layout[buffer_index].pipeline_layout, VK_SHADER_STAGE_FRAGMENT_BIT,
  1115. 0, sizeof render_data->push_constants, &render_data->push_constants);
  1116. vkCmdDrawIndexed(cmd_buffer, 3, 1, 0, 0, 0);
  1117. vkCmdEndRenderPass(cmd_buffer);
  1118. image_barrier = (VkImageMemoryBarrier){
  1119. .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
  1120. .srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT,
  1121. .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
  1122. .oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
  1123. .newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
  1124. .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
  1125. .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
  1126. .image = render_data->buf_obuffers[render_index + buffer_index * 2].color.image,
  1127. .subresourceRange =
  1128. {
  1129. .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
  1130. .baseMipLevel = 0,
  1131. .levelCount = 1,
  1132. .baseArrayLayer = 0,
  1133. .layerCount = 1,
  1134. },
  1135. };
  1136. vkCmdPipelineBarrier(cmd_buffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0,
  1137. NULL, 0, NULL, 1, &image_barrier);
  1138. vkEndCommandBuffer(cmd_buffer);
  1139. return true;
  1140. }
  1141. static bool render_loop_draw(struct vk_physical_device *phy_dev, struct vk_device *dev, struct vk_swapchain *swapchain,
  1142. struct app_os_window *os_window)
  1143. {
  1144. if (!os_window->prepared) return true;
  1145. static int render_index = 0;
  1146. int res;
  1147. vk_error retval = VK_ERROR_NONE;
  1148. set_push_constants(os_window);
  1149. if (!update_iKeyboard_texture(phy_dev, dev, &essentials, &render_data))
  1150. return false;
  1151. for (int i = 0; i < OFFSCREEN_BUFFERS; i++)
  1152. {
  1153. if (!render_loop_buf(phy_dev, dev, &essentials, &render_data, offscreen_cmd_buffer[i], render_index, i,
  1154. &os_window->app_data))
  1155. {
  1156. printf("Error on rendering buffers \n");
  1157. return false;
  1158. }
  1159. update_push_constants_window_size(os_window);
  1160. if (i == 0)
  1161. { // wait main screen
  1162. if (!first_submission)
  1163. {
  1164. res = vkWaitForFences(dev->device, 1, &offscreen_fence, true, 1000000000);
  1165. vk_error_set_vkresult(&retval, res);
  1166. if (res)
  1167. {
  1168. vk_error_printf(&retval, "Wait for main fence failed\n");
  1169. return false;
  1170. }
  1171. }
  1172. VkPipelineStageFlags wait_sem_stages[1] = {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT};
  1173. VkSubmitInfo submit_info = {
  1174. .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
  1175. .waitSemaphoreCount = first_submission ? 0 : 1,
  1176. .pWaitSemaphores = &wait_main_sem,
  1177. .pWaitDstStageMask = wait_sem_stages,
  1178. .commandBufferCount = 1,
  1179. .pCommandBuffers = &offscreen_cmd_buffer[i],
  1180. .signalSemaphoreCount = 1,
  1181. .pSignalSemaphores = &wait_buf_sem,
  1182. };
  1183. res = vkResetFences(dev->device, 1, &offscreen_fence);
  1184. vk_error_set_vkresult(&retval, res);
  1185. if (res)
  1186. {
  1187. vk_error_printf(&retval, "Failed to reset fence\n");
  1188. return false;
  1189. }
  1190. vkQueueSubmit(offscreen_queue[i], 1, &submit_info, offscreen_fence);
  1191. first_submission = false;
  1192. }
  1193. else
  1194. { // wait last buf/shader in loop, if multi VkQueue supported
  1195. res = vkWaitForFences(dev->device, 1, &offscreen_fence, true, 1000000000);
  1196. vk_error_set_vkresult(&retval, res);
  1197. if (res)
  1198. {
  1199. vk_error_printf(&retval, "Wait for buf fence failed\n");
  1200. return false;
  1201. }
  1202. VkPipelineStageFlags wait_sem_stages[1] = {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT};
  1203. VkSubmitInfo submit_info = {
  1204. .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
  1205. .waitSemaphoreCount = 1,
  1206. .pWaitSemaphores = &wait_buf_sem,
  1207. .pWaitDstStageMask = wait_sem_stages,
  1208. .commandBufferCount = 1,
  1209. .pCommandBuffers = &offscreen_cmd_buffer[i],
  1210. .signalSemaphoreCount = 1,
  1211. .pSignalSemaphores = &wait_main_sem, // used main sem
  1212. };
  1213. res = vkResetFences(dev->device, 1, &offscreen_fence);
  1214. vk_error_set_vkresult(&retval, res);
  1215. if (res)
  1216. {
  1217. vk_error_printf(&retval, "Failed to reset fence\n");
  1218. return false;
  1219. }
  1220. vkQueueSubmit(offscreen_queue[i], 1, &submit_info, offscreen_fence);
  1221. VkSemaphore tmp_sem = wait_buf_sem;
  1222. wait_buf_sem = wait_main_sem;
  1223. wait_main_sem = tmp_sem;
  1224. }
  1225. }
  1226. uint32_t image_index;
  1227. res = vk_render_start(&essentials, dev, swapchain, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, &image_index);
  1228. if (res == VK_ERROR_OUT_OF_DATE_KHR)
  1229. {
  1230. os_window->resize_event = true;
  1231. res = 0;
  1232. first_submission = true;
  1233. return true;
  1234. }
  1235. else if (res == VK_ERROR_SURFACE_LOST_KHR)
  1236. {
  1237. vkDestroySurfaceKHR(vk, swapchain->surface, NULL);
  1238. retval = vk_create_surface(vk, &swapchain->surface, os_window);
  1239. if (!vk_error_is_success(&retval))
  1240. return false;
  1241. os_window->resize_event = true;
  1242. res = 0;
  1243. first_submission = true;
  1244. return true;
  1245. }
  1246. if (res)
  1247. return false;
  1248. VkClearValue clear_values = {
  1249. .color =
  1250. {
  1251. .float32 = {0.0, 0.0, 0.0, 0.0},
  1252. },
  1253. };
  1254. VkRenderPassBeginInfo pass_info = {
  1255. .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
  1256. .renderPass = render_data.main_render_pass,
  1257. .framebuffer = render_data.main_gbuffers[image_index].framebuffer,
  1258. .renderArea =
  1259. {
  1260. .offset =
  1261. {
  1262. .x = 0,
  1263. .y = 0,
  1264. },
  1265. .extent = render_data.main_gbuffers[image_index].surface_size,
  1266. },
  1267. .clearValueCount = 1,
  1268. .pClearValues = &clear_values,
  1269. };
  1270. vkCmdBeginRenderPass(essentials.cmd_buffer, &pass_info, VK_SUBPASS_CONTENTS_INLINE);
  1271. vkCmdBindPipeline(essentials.cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, render_data.main_pipeline.pipeline);
  1272. VkDescriptorImageInfo set_write_image_info[IMAGE_TEXTURES + OFFSCREEN_BUFFERS + iKeyboard] = {0};
  1273. for (uint32_t i = 0; i < IMAGE_TEXTURES; i++)
  1274. {
  1275. set_write_image_info[i] = (VkDescriptorImageInfo){
  1276. .sampler = render_data.images[i].sampler,
  1277. .imageView = render_data.images[i].view,
  1278. .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
  1279. };
  1280. }
  1281. for (uint32_t i = 0; i < OFFSCREEN_BUFFERS; i++)
  1282. {
  1283. set_write_image_info[IMAGE_TEXTURES + i] = (VkDescriptorImageInfo){
  1284. .sampler = render_data.buf_obuffers[i * 2 + render_index].color.sampler,
  1285. .imageView = render_data.buf_obuffers[i * 2 + render_index].color.view,
  1286. .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
  1287. };
  1288. }
  1289. set_write_image_info[IMAGE_TEXTURES + OFFSCREEN_BUFFERS] = (VkDescriptorImageInfo){
  1290. .sampler = render_data.images[IMAGE_TEXTURES + OFFSCREEN_BUFFERS].sampler,
  1291. .imageView = render_data.images[IMAGE_TEXTURES + OFFSCREEN_BUFFERS].view,
  1292. .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
  1293. };
  1294. VkWriteDescriptorSet set_write[3] = {
  1295. [0] =
  1296. {
  1297. .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
  1298. .dstSet = render_data.main_desc_set,
  1299. .dstBinding = 0,
  1300. .descriptorCount = IMAGE_TEXTURES,
  1301. .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
  1302. .pImageInfo = &set_write_image_info[0],
  1303. },
  1304. [1] =
  1305. {
  1306. .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
  1307. .dstSet = render_data.main_desc_set,
  1308. .dstBinding = IMAGE_TEXTURES,
  1309. .descriptorCount = OFFSCREEN_BUFFERS,
  1310. .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
  1311. .pImageInfo = &set_write_image_info[IMAGE_TEXTURES],
  1312. },
  1313. [2] =
  1314. {
  1315. .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
  1316. .dstSet = render_data.main_desc_set,
  1317. .dstBinding = IMAGE_TEXTURES + OFFSCREEN_BUFFERS,
  1318. .descriptorCount = iKeyboard,
  1319. .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
  1320. .pImageInfo = &set_write_image_info[IMAGE_TEXTURES + OFFSCREEN_BUFFERS],
  1321. },
  1322. };
  1323. vkUpdateDescriptorSets(dev->device, 3, set_write, 0, NULL);
  1324. vkCmdBindDescriptorSets(essentials.cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
  1325. render_data.main_layout.pipeline_layout, 0, 1, &render_data.main_desc_set, 0, NULL);
  1326. VkDeviceSize vertices_offset = 0;
  1327. vkCmdBindVertexBuffers(essentials.cmd_buffer, 0, 1, &render_data.buffers[BUFFER_VERTICES].buffer, &vertices_offset);
  1328. vkCmdBindIndexBuffer(essentials.cmd_buffer, render_data.buffers[BUFFER_INDICES].buffer, 0, VK_INDEX_TYPE_UINT16);
  1329. VkViewport viewport = {
  1330. .x = 0,
  1331. .y = 0,
  1332. .width = render_data.main_gbuffers[image_index].surface_size.width,
  1333. .height = render_data.main_gbuffers[image_index].surface_size.height,
  1334. .minDepth = 0,
  1335. .maxDepth = 1,
  1336. };
  1337. vkCmdSetViewport(essentials.cmd_buffer, 0, 1, &viewport);
  1338. VkRect2D scissor = {
  1339. .offset =
  1340. {
  1341. .x = 0,
  1342. .y = 0,
  1343. },
  1344. .extent = render_data.main_gbuffers[image_index].surface_size,
  1345. };
  1346. vkCmdSetScissor(essentials.cmd_buffer, 0, 1, &scissor);
  1347. vkCmdPushConstants(essentials.cmd_buffer, render_data.main_layout.pipeline_layout, VK_SHADER_STAGE_FRAGMENT_BIT, 0,
  1348. sizeof render_data.push_constants, &render_data.push_constants);
  1349. // vkCmdDraw(essentials.cmd_buffer, 3, 1, 0, 0);
  1350. vkCmdDrawIndexed(essentials.cmd_buffer, 3, 1, 0, 0, 0);
  1351. vkCmdEndRenderPass(essentials.cmd_buffer);
  1352. res = vk_render_finish(&essentials, dev, swapchain, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, image_index,
  1353. wait_buf_sem, wait_main_sem);
  1354. if (res == VK_ERROR_OUT_OF_DATE_KHR)
  1355. {
  1356. os_window->resize_event = true;
  1357. res = 0;
  1358. }
  1359. else if (res == VK_ERROR_SURFACE_LOST_KHR)
  1360. {
  1361. vkDestroySurfaceKHR(vk, swapchain->surface, NULL);
  1362. retval = vk_create_surface(vk, &swapchain->surface, os_window);
  1363. if (!vk_error_is_success(&retval))
  1364. return false;
  1365. os_window->resize_event = true;
  1366. res = 0;
  1367. }
  1368. if (res)
  1369. return false;
  1370. #ifdef USE_SCREENSHOT
  1371. if(screenshot_once){
  1372. screenshot_once = false;
  1373. retval = make_screenshot(phy_dev, dev, swapchain, &essentials, image_index);
  1374. if (!vk_error_is_success(&retval))
  1375. return false;
  1376. }
  1377. #endif
  1378. update_params(&os_window->app_data, os_window->fps_lock);
  1379. render_index = (render_index + 1) % 2;
  1380. os_window->pause_refresh = false;
  1381. return true;
  1382. }
  1383. void init_win_params(struct app_os_window *os_window)
  1384. {
  1385. os_window->app_data.iResolution[0] = 1280;
  1386. os_window->app_data.iResolution[1] = 720;
  1387. #if defined(VK_USE_PLATFORM_WAYLAND_KHR)
  1388. resize_size[0] = os_window->app_data.iResolution[0];
  1389. resize_size[1] = os_window->app_data.iResolution[1];
  1390. #endif
  1391. os_window->app_data.iFrame = 0;
  1392. os_window->app_data.iMouse[0] = 0;
  1393. os_window->app_data.iMouse[1] = 0;
  1394. os_window->app_data.iMouse_click[0] = false;
  1395. os_window->app_data.iMouse_click[1] = false;
  1396. os_window->app_data.iMouse_lclick[0] = 0;
  1397. os_window->app_data.iMouse_lclick[1] = 0;
  1398. os_window->app_data.iTime = 0;
  1399. os_window->app_data.pause = false;
  1400. os_window->app_data.quit = false;
  1401. os_window->app_data.drawdebug = false;
  1402. os_window->fps_lock = false;
  1403. os_window->is_minimized = false;
  1404. os_window->prepared = false;
  1405. os_window->resize_event = false;
  1406. os_window->reload_shaders_on_resize = false;
  1407. os_window->print_debug = false;
  1408. os_window->pause_refresh = false;
  1409. strncpy(os_window->name, "Vulkan Shadertoy launcher", APP_NAME_STR_LEN);
  1410. #if defined(VK_USE_PLATFORM_WIN32_KHR)
  1411. os_window->connection = NULL;
  1412. os_window->window = NULL;
  1413. os_window->minsize.x = 1;
  1414. os_window->minsize.y = 1;
  1415. #elif defined(VK_USE_PLATFORM_XCB_KHR)
  1416. os_window->atom_wm_delete_window = NULL;
  1417. os_window->xcb_window = 0;
  1418. os_window->screen = NULL;
  1419. os_window->connection = NULL;
  1420. os_window->display = NULL;
  1421. #elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
  1422. os_window->display = NULL;
  1423. os_window->registry = NULL;
  1424. os_window->compositor = NULL;
  1425. os_window->surface = NULL;
  1426. os_window->shell = NULL;
  1427. os_window->seat = NULL;
  1428. os_window->pointer = NULL;
  1429. os_window->keyboard = NULL;
  1430. os_window->xdg_surface = NULL;
  1431. os_window->xdg_toplevel = NULL;
  1432. os_window->configured = false;
  1433. #endif
  1434. }
  1435. #if defined(VK_USE_PLATFORM_XCB_KHR)
  1436. bool enterFullscreen() {
  1437. // idk how to make borderless fullscren on xcb
  1438. return true;
  1439. }
  1440. static void render_loop_xcb(struct vk_physical_device *phy_dev, struct vk_device *dev, struct vk_swapchain *swapchain,
  1441. struct app_os_window *os_window)
  1442. {
  1443. while (!os_window->app_data.quit)
  1444. {
  1445. update_keypress();
  1446. xcb_generic_event_t *event;
  1447. if (os_window->app_data.pause)
  1448. {
  1449. event = xcb_wait_for_event(os_window->connection);
  1450. }
  1451. else
  1452. {
  1453. event = xcb_poll_for_event(os_window->connection);
  1454. }
  1455. // a workaround for repeated key events
  1456. // save original state of each modifyed button and check if it was modifyed twice
  1457. bool save_map[0xff + 1][3] = {0};
  1458. bool state_map[0xff + 1][2] = {0};
  1459. while (event)
  1460. {
  1461. app_handle_xcb_event(os_window, event, save_map, state_map);
  1462. free(event);
  1463. event = xcb_poll_for_event(os_window->connection);
  1464. }
  1465. if (keyboard_need_update)
  1466. {
  1467. for (int i = 0; i < 0xff; i++)
  1468. {
  1469. if ((state_map[i][0]) && (state_map[i][1]))
  1470. {
  1471. update_key_map(i, 0, save_map[i][0]);
  1472. update_key_map(i, 1, save_map[i][1]);
  1473. update_key_map(i, 2, save_map[i][2]);
  1474. }
  1475. }
  1476. }
  1477. check_hotkeys(os_window);
  1478. if ((!os_window->is_minimized) && (!os_window->resize_event))
  1479. {
  1480. if (!os_window->app_data.quit)
  1481. {
  1482. os_window->app_data.quit = !render_loop_draw(phy_dev, dev, swapchain, os_window);
  1483. }
  1484. else
  1485. break;
  1486. }
  1487. else
  1488. {
  1489. if ((!os_window->is_minimized) && os_window->resize_event)
  1490. {
  1491. on_window_resize(phy_dev, dev, &essentials, swapchain, &render_data,
  1492. os_window); // execute draw or resize per frame, not together
  1493. os_window->resize_event=false;
  1494. }
  1495. }
  1496. if (os_window->is_minimized)
  1497. { // I do not delete everything on minimize, only stop rendering
  1498. sleep_ms(16);
  1499. }
  1500. }
  1501. exit_cleanup_render_loop(dev, &essentials, &render_data, wait_buf_sem, wait_main_sem, offscreen_fence);
  1502. }
  1503. #elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
  1504. static void render_loop_wayland(struct vk_physical_device *phy_dev, struct vk_device *dev, struct vk_swapchain *swapchain,
  1505. struct app_os_window *os_window)
  1506. {
  1507. static bool init_surface_size_once=true; // in Wayland surface should set window size, I do it on start, on start window size 0,0
  1508. while (!os_window->app_data.quit)
  1509. {
  1510. update_keypress();
  1511. while (!os_window->configured)
  1512. wl_display_dispatch(os_window->display);
  1513. while (wl_display_prepare_read(os_window->display) != 0)
  1514. wl_display_dispatch_pending(os_window->display);
  1515. wl_display_flush(os_window->display);
  1516. wl_display_read_events(os_window->display);
  1517. wl_display_dispatch_pending(os_window->display);
  1518. check_hotkeys(os_window);
  1519. if (((!os_window->is_minimized) && (!os_window->resize_event)&&((!os_window->app_data.pause)||((os_window->app_data.pause)&&(os_window->pause_refresh))))
  1520. || init_surface_size_once)
  1521. {
  1522. if (!os_window->app_data.quit)
  1523. {
  1524. os_window->app_data.quit = !render_loop_draw(phy_dev, dev, swapchain, os_window);
  1525. }
  1526. else
  1527. break;
  1528. init_surface_size_once = false;
  1529. }
  1530. else
  1531. {
  1532. if ((!os_window->is_minimized) && os_window->resize_event)
  1533. {
  1534. on_window_resize(phy_dev, dev, &essentials, swapchain, &render_data,
  1535. os_window);
  1536. }
  1537. }
  1538. if(os_window->is_minimized||(((os_window->app_data.pause)&&(!os_window->pause_refresh)))){ //I do not delete everything on minimize, only stop rendering
  1539. sleep_ms(16);
  1540. }
  1541. }
  1542. exit_cleanup_render_loop(dev, &essentials, &render_data, wait_buf_sem, wait_main_sem, offscreen_fence);
  1543. }
  1544. #endif
  1545. void print_usage(char *name)
  1546. {
  1547. printf("Usage: %s \n"
  1548. "\t[--present_mode <present mode enum>]\n"
  1549. "\t <present_mode_enum>\tVK_PRESENT_MODE_IMMEDIATE_KHR = %d\n"
  1550. "\t\t\t\tVK_PRESENT_MODE_MAILBOX_KHR = %d\n"
  1551. "\t\t\t\tVK_PRESENT_MODE_FIFO_KHR = %d\n"
  1552. "\t\t\t\tVK_PRESENT_MODE_FIFO_RELAXED_KHR = %d\n"
  1553. "\t[--debug]\n"
  1554. "\t[--reload_shaders] will reload shaders form file on resize\n"
  1555. "\t[--gpu <index(0/1/2/etc)>] use selected GPU to render\n"
  1556. "Control: Keyboard 1-debug, 2-vsynk 60fps, Space-pause\n",
  1557. name, VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_FIFO_KHR,
  1558. VK_PRESENT_MODE_FIFO_RELAXED_KHR);
  1559. }
  1560. #if defined(VK_USE_PLATFORM_WIN32_KHR)
  1561. static int old_w, old_h;
  1562. static RECT rcClient, rcWind;
  1563. bool exitFullscreen();
  1564. bool enterFullscreen() {
  1565. return true;
  1566. // for some reason this code works only on Nvidia, on AMD it does not work(crash)
  1567. /*
  1568. if (!chWnd)return false;
  1569. if (fullscreen){return exitFullscreen();}
  1570. HWND hwnd = chWnd;
  1571. POINT ptDiff;
  1572. GetClientRect(hwnd, &rcClient);
  1573. GetWindowRect(hwnd, &rcWind);
  1574. ptDiff.x = (rcWind.right - rcWind.left) - rcClient.right;
  1575. ptDiff.y = (rcWind.bottom - rcWind.top) - rcClient.bottom;
  1576. old_w = os_window.app_data.iResolution[0]+ptDiff.x;
  1577. old_h = os_window.app_data.iResolution[1]+ptDiff.y;
  1578. int fullscreenWidth = GetSystemMetrics(SM_CXSCREEN);
  1579. int fullscreenHeight = GetSystemMetrics(SM_CYSCREEN);
  1580. LONG lStyle = GetWindowLong(hwnd, GWL_STYLE);
  1581. lStyle &= ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU);
  1582. SetWindowLong(hwnd, GWL_STYLE, lStyle);
  1583. LONG lExStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
  1584. lExStyle &= ~(WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE);
  1585. SetWindowLong(hwnd, GWL_EXSTYLE, lExStyle);
  1586. SetWindowPos(hwnd, HWND_TOP, 0, 0, fullscreenWidth, fullscreenHeight, SWP_SHOWWINDOW); //HWND_TOPMOST
  1587. SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER);
  1588. fullscreen = true;
  1589. return true;
  1590. */
  1591. }
  1592. bool exitFullscreen() {
  1593. if (!chWnd)return false;
  1594. HWND hwnd = chWnd;
  1595. SetWindowLongPtr(hwnd, GWL_EXSTYLE, WS_EX_LEFT);
  1596. SetWindowLongPtr(hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE);
  1597. SetWindowPos(hwnd, HWND_NOTOPMOST, rcWind.left, rcWind.top, old_w, old_h, SWP_SHOWWINDOW);
  1598. fullscreen = false;
  1599. return true;
  1600. }
  1601. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, int nCmdShow)
  1602. {
  1603. MSG msg;
  1604. bool done;
  1605. int argc;
  1606. char **argv;
  1607. msg.wParam = 0;
  1608. LPWSTR *commandLineArgs = CommandLineToArgvW(GetCommandLineW(), &argc);
  1609. if (NULL == commandLineArgs)
  1610. {
  1611. argc = 0;
  1612. }
  1613. if (argc > 0)
  1614. {
  1615. argv = (char **)malloc(sizeof(char *) * argc);
  1616. if (argv == NULL)
  1617. {
  1618. argc = 0;
  1619. }
  1620. else
  1621. {
  1622. for (int iii = 0; iii < argc; iii++)
  1623. {
  1624. size_t wideCharLen = wcslen(commandLineArgs[iii]);
  1625. size_t numConverted = 0;
  1626. argv[iii] = (char *)malloc(sizeof(char) * (wideCharLen + 1));
  1627. if (argv[iii] != NULL)
  1628. {
  1629. wcstombs_s(&numConverted, argv[iii], wideCharLen + 1, commandLineArgs[iii], wideCharLen + 1);
  1630. }
  1631. }
  1632. }
  1633. }
  1634. else
  1635. {
  1636. argv = NULL;
  1637. }
  1638. vk_error res = VK_ERROR_NONE;
  1639. int retval = EXIT_FAILURE;
  1640. init_win_params(&os_window);
  1641. uint32_t dev_index = 0;
  1642. bool use_gpu_idx = false;
  1643. os_window.present_mode = VK_PRESENT_MODE_FIFO_KHR;
  1644. if (argc > 1)
  1645. {
  1646. if (strcmp(argv[1], "--help") == 0)
  1647. {
  1648. SetStdOutToNewConsole();
  1649. print_usage(argv[0]);
  1650. Sleep(44000);
  1651. return 0;
  1652. }
  1653. }
  1654. for (int i = 1; i < argc; i++)
  1655. {
  1656. if ((strcmp(argv[i], "--present_mode") == 0) && (i < argc - 1))
  1657. {
  1658. os_window.present_mode = atoi(argv[i + 1]);
  1659. i++;
  1660. continue;
  1661. }
  1662. if ((strcmp(argv[i], "--gpu") == 0) && (i < argc - 1))
  1663. {
  1664. dev_index = atoi(argv[i + 1]);
  1665. use_gpu_idx = true;
  1666. i++;
  1667. continue;
  1668. }
  1669. if (strcmp(argv[i], "--debug") == 0)
  1670. {
  1671. os_window.print_debug = true;
  1672. continue;
  1673. }
  1674. if (strcmp(argv[i], "--reload_shaders") == 0)
  1675. {
  1676. os_window.reload_shaders_on_resize = true;
  1677. continue;
  1678. }
  1679. }
  1680. if (argc > 0 && argv != NULL)
  1681. {
  1682. for (int iii = 0; iii < argc; iii++)
  1683. {
  1684. if (argv[iii] != NULL)
  1685. {
  1686. free(argv[iii]);
  1687. }
  1688. }
  1689. free(argv);
  1690. }
  1691. if (os_window.print_debug)
  1692. {
  1693. SetStdOutToNewConsole();
  1694. }
  1695. os_window.connection = hInstance;
  1696. res = vk_init(&vk);
  1697. if (!vk_error_is_success(&res))
  1698. {
  1699. vk_error_printf(&res, "Could not initialize Vulkan\n");
  1700. return retval;
  1701. }
  1702. app_create_window(&os_window);
  1703. res = vk_create_surface(vk, &swapchain.surface, &os_window);
  1704. if (vk_error_is_error(&res))
  1705. {
  1706. vk_error_printf(&res, "Could not create surface.\n");
  1707. exit_cleanup(vk, NULL, NULL, &os_window);
  1708. return retval;
  1709. }
  1710. res = vk_enumerate_devices(vk, &swapchain.surface, &phy_dev, &dev_index, use_gpu_idx);
  1711. if (vk_error_is_error(&res))
  1712. {
  1713. vk_error_printf(&res, "Could not enumerate devices\n");
  1714. vkDestroySurfaceKHR(vk, swapchain.surface, NULL);
  1715. exit_cleanup(vk, NULL, NULL, &os_window);
  1716. return retval;
  1717. }
  1718. res = vk_setup(&phy_dev, &dev, VK_QUEUE_GRAPHICS_BIT,
  1719. 1 + OFFSCREEN_BUFFERS); // using number of command buffers equal to offscreen buffers
  1720. if (vk_error_is_error(&res))
  1721. {
  1722. vk_error_printf(&res, "Could not setup logical device, command pools and queues\n");
  1723. exit_cleanup(vk, &dev, &swapchain, &os_window);
  1724. return retval;
  1725. }
  1726. swapchain.swapchain = VK_NULL_HANDLE;
  1727. res = vk_get_swapchain(vk, &phy_dev, &dev, &swapchain, &os_window, 1, &os_window.present_mode);
  1728. if (vk_error_is_error(&res))
  1729. {
  1730. vk_error_printf(&res, "Could not create surface and swapchain\n");
  1731. exit_cleanup(vk, &dev, &swapchain, &os_window);
  1732. return retval;
  1733. }
  1734. render_loop_init(&phy_dev, &dev, &swapchain, &os_window);
  1735. done = false;
  1736. while (!done)
  1737. {
  1738. PeekMessage(&msg, 0, 0, 0, PM_REMOVE);
  1739. process_msg(&msg, &done);
  1740. RedrawWindow(os_window.window, NULL, NULL, RDW_INTERNALPAINT);
  1741. }
  1742. exit_cleanup_render_loop(&dev, &essentials, &render_data, wait_buf_sem, wait_main_sem, offscreen_fence);
  1743. exit_cleanup(vk, &dev, &swapchain, &os_window);
  1744. return (int)msg.wParam;
  1745. }
  1746. #elif defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_WAYLAND_KHR)
  1747. int main(int argc, char **argv)
  1748. {
  1749. vk_error res;
  1750. int retval = EXIT_FAILURE;
  1751. VkInstance vk;
  1752. struct vk_physical_device phy_dev = {0};
  1753. struct vk_device dev = {0};
  1754. struct vk_swapchain swapchain = {0};
  1755. struct app_os_window os_window;
  1756. init_win_params(&os_window);
  1757. uint32_t dev_index = 0;
  1758. bool use_gpu_idx = false;
  1759. os_window.present_mode = VK_PRESENT_MODE_FIFO_KHR;
  1760. if (argc > 1)
  1761. {
  1762. if (strcmp(argv[1], "--help") == 0)
  1763. {
  1764. print_usage(argv[0]);
  1765. return 0;
  1766. }
  1767. }
  1768. for (int i = 1; i < argc; i++)
  1769. {
  1770. if ((strcmp(argv[i], "--present_mode") == 0) && (i < argc - 1))
  1771. {
  1772. os_window.present_mode = atoi(argv[i + 1]);
  1773. i++;
  1774. continue;
  1775. }
  1776. if ((strcmp(argv[i], "--gpu") == 0) && (i < argc - 1))
  1777. {
  1778. dev_index = atoi(argv[i + 1]);
  1779. use_gpu_idx = true;
  1780. i++;
  1781. continue;
  1782. }
  1783. if (strcmp(argv[i], "--debug") == 0)
  1784. {
  1785. os_window.print_debug = true;
  1786. continue;
  1787. }
  1788. if (strcmp(argv[i], "--reload_shaders") == 0)
  1789. {
  1790. os_window.reload_shaders_on_resize = true;
  1791. continue;
  1792. }
  1793. }
  1794. srand(time(NULL));
  1795. res = vk_init(&vk);
  1796. if (!vk_error_is_success(&res))
  1797. {
  1798. vk_error_printf(&res, "Could not initialize Vulkan\n");
  1799. return retval;
  1800. }
  1801. #if defined(VK_USE_PLATFORM_XCB_KHR)
  1802. printf("Init XCB\n");
  1803. app_init_connection(&os_window);
  1804. app_create_xcb_window(&os_window);
  1805. #else
  1806. printf("Init Wayland\n");
  1807. initWaylandConnection(&os_window);
  1808. setupWindow(&os_window);
  1809. #endif
  1810. res = vk_create_surface(vk, &swapchain.surface, &os_window);
  1811. if (vk_error_is_error(&res))
  1812. {
  1813. vk_error_printf(&res, "Could not create surface.\n");
  1814. exit_cleanup(vk, NULL, NULL, &os_window);
  1815. return retval;
  1816. }
  1817. res = vk_enumerate_devices(vk, &swapchain.surface, &phy_dev, &dev_index, use_gpu_idx);
  1818. if (vk_error_is_error(&res))
  1819. {
  1820. vk_error_printf(&res, "Could not enumerate devices\n");
  1821. vkDestroySurfaceKHR(vk, swapchain.surface, NULL);
  1822. exit_cleanup(vk, NULL, NULL, &os_window);
  1823. return retval;
  1824. }
  1825. res = vk_setup(&phy_dev, &dev, VK_QUEUE_GRAPHICS_BIT, 1 + OFFSCREEN_BUFFERS); // cmd buffers alloc
  1826. if (vk_error_is_error(&res))
  1827. {
  1828. vk_error_printf(&res, "Could not setup logical device, command pools and queues\n");
  1829. exit_cleanup(vk, &dev, &swapchain, &os_window);
  1830. return retval;
  1831. }
  1832. swapchain.swapchain = VK_NULL_HANDLE;
  1833. res = vk_get_swapchain(vk, &phy_dev, &dev, &swapchain, &os_window, 1, &os_window.present_mode);
  1834. if (vk_error_is_error(&res))
  1835. {
  1836. vk_error_printf(&res, "Could not create surface and swapchain\n");
  1837. exit_cleanup(vk, &dev, &swapchain, &os_window);
  1838. return retval;
  1839. }
  1840. render_loop_init(&phy_dev, &dev, &swapchain, &os_window);
  1841. #if defined(VK_USE_PLATFORM_XCB_KHR)
  1842. render_loop_xcb(&phy_dev, &dev, &swapchain, &os_window);
  1843. #else
  1844. render_loop_wayland(&phy_dev, &dev, &swapchain, &os_window);
  1845. #endif
  1846. retval = 0;
  1847. exit_cleanup(vk, &dev, &swapchain, &os_window);
  1848. return retval;
  1849. }
  1850. #endif