RendererVK.cpp 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2024 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #include <TestFramework.h>
  5. #include <Renderer/VK/RendererVK.h>
  6. #include <Renderer/VK/RenderPrimitiveVK.h>
  7. #include <Renderer/VK/RenderInstancesVK.h>
  8. #include <Renderer/VK/PipelineStateVK.h>
  9. #include <Renderer/VK/VertexShaderVK.h>
  10. #include <Renderer/VK/PixelShaderVK.h>
  11. #include <Renderer/VK/TextureVK.h>
  12. #include <Renderer/VK/FatalErrorIfFailedVK.h>
  13. #include <Utils/Log.h>
  14. #include <Utils/ReadData.h>
  15. #include <Jolt/Core/Profiler.h>
  16. #include <Jolt/Core/QuickSort.h>
  17. #include <Jolt/Core/RTTI.h>
  18. JPH_SUPPRESS_WARNINGS_STD_BEGIN
  19. #ifdef JPH_PLATFORM_WINDOWS
  20. #include <vulkan/vulkan_win32.h>
  21. #include <Window/ApplicationWindowWin.h>
  22. #elif defined(JPH_PLATFORM_LINUX)
  23. #include <vulkan/vulkan_xlib.h>
  24. #include <Window/ApplicationWindowLinux.h>
  25. #elif defined(JPH_PLATFORM_MACOS)
  26. #include <vulkan/vulkan_metal.h>
  27. #include <Window/ApplicationWindowMacOS.h>
  28. #endif
  29. JPH_SUPPRESS_WARNINGS_STD_END
  30. #ifdef JPH_DEBUG
  31. static VKAPI_ATTR VkBool32 VKAPI_CALL sVulkanDebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT inSeverity, [[maybe_unused]] VkDebugUtilsMessageTypeFlagsEXT inType, const VkDebugUtilsMessengerCallbackDataEXT *inCallbackData, [[maybe_unused]] void *inUserData)
  32. {
  33. Trace("VK: %s", inCallbackData->pMessage);
  34. JPH_ASSERT((inSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) == 0);
  35. return VK_FALSE;
  36. }
  37. #endif // JPH_DEBUG
  38. RendererVK::~RendererVK()
  39. {
  40. vkDeviceWaitIdle(mDevice);
  41. // Trace allocation stats
  42. Trace("VK: Max allocations: %u, max size: %u MB", mMaxNumAllocations, uint32(mMaxTotalAllocated >> 20));
  43. // Destroy the shadow map
  44. mShadowMap = nullptr;
  45. vkDestroyFramebuffer(mDevice, mShadowFrameBuffer, nullptr);
  46. // Release constant buffers
  47. for (unique_ptr<ConstantBufferVK> &cb : mVertexShaderConstantBufferProjection)
  48. cb = nullptr;
  49. for (unique_ptr<ConstantBufferVK> &cb : mVertexShaderConstantBufferOrtho)
  50. cb = nullptr;
  51. for (unique_ptr<ConstantBufferVK> &cb : mPixelShaderConstantBuffer)
  52. cb = nullptr;
  53. // Free all buffers
  54. for (BufferCache &bc : mFreedBuffers)
  55. for (BufferCache::value_type &vt : bc)
  56. for (BufferVK &bvk : vt.second)
  57. FreeBufferInternal(bvk);
  58. for (BufferCache::value_type &vt : mBufferCache)
  59. for (BufferVK &bvk : vt.second)
  60. FreeBufferInternal(bvk);
  61. // Free all blocks in the memory cache
  62. for (MemoryCache::value_type &mc : mMemoryCache)
  63. for (Memory &m : mc.second)
  64. if (m.mOffset == 0)
  65. vkFreeMemory(mDevice, m.mMemory, nullptr); // Don't care about memory tracking anymore
  66. for (VkFence fence : mInFlightFences)
  67. vkDestroyFence(mDevice, fence, nullptr);
  68. for (VkSemaphore semaphore : mRenderFinishedSemaphores)
  69. vkDestroySemaphore(mDevice, semaphore, nullptr);
  70. for (VkSemaphore semaphore : mImageAvailableSemaphores)
  71. vkDestroySemaphore(mDevice, semaphore, nullptr);
  72. vkDestroyCommandPool(mDevice, mCommandPool, nullptr);
  73. vkDestroyPipelineLayout(mDevice, mPipelineLayout, nullptr);
  74. vkDestroyRenderPass(mDevice, mRenderPassShadow, nullptr);
  75. vkDestroyRenderPass(mDevice, mRenderPass, nullptr);
  76. vkDestroyDescriptorPool(mDevice, mDescriptorPool, nullptr);
  77. vkDestroySampler(mDevice, mTextureSamplerShadow, nullptr);
  78. vkDestroySampler(mDevice, mTextureSamplerRepeat, nullptr);
  79. vkDestroyDescriptorSetLayout(mDevice, mDescriptorSetLayoutUBO, nullptr);
  80. vkDestroyDescriptorSetLayout(mDevice, mDescriptorSetLayoutTexture, nullptr);
  81. DestroySwapChain();
  82. vkDestroySurfaceKHR(mInstance, mSurface, nullptr);
  83. vkDestroyDevice(mDevice, nullptr);
  84. #ifdef JPH_DEBUG
  85. PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT = (PFN_vkDestroyDebugUtilsMessengerEXT)(void *)vkGetInstanceProcAddr(mInstance, "vkDestroyDebugUtilsMessengerEXT");
  86. if (vkDestroyDebugUtilsMessengerEXT != nullptr)
  87. vkDestroyDebugUtilsMessengerEXT(mInstance, mDebugMessenger, nullptr);
  88. #endif
  89. vkDestroyInstance(mInstance, nullptr);
  90. }
  91. void RendererVK::Initialize(ApplicationWindow *inWindow)
  92. {
  93. Renderer::Initialize(inWindow);
  94. // Flip the sign of the projection matrix
  95. mPerspectiveYSign = -1.0f;
  96. // Required instance extensions
  97. Array<const char *> required_instance_extensions;
  98. required_instance_extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
  99. #ifdef JPH_PLATFORM_WINDOWS
  100. required_instance_extensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
  101. #elif defined(JPH_PLATFORM_LINUX)
  102. required_instance_extensions.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
  103. #elif defined(JPH_PLATFORM_MACOS)
  104. required_instance_extensions.push_back(VK_EXT_METAL_SURFACE_EXTENSION_NAME);
  105. required_instance_extensions.push_back("VK_KHR_portability_enumeration");
  106. required_instance_extensions.push_back("VK_KHR_get_physical_device_properties2");
  107. #endif
  108. // Required device extensions
  109. Array<const char *> required_device_extensions;
  110. required_device_extensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
  111. #ifdef JPH_PLATFORM_MACOS
  112. required_device_extensions.push_back("VK_KHR_portability_subset"); // VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME
  113. #endif
  114. // Query supported instance extensions
  115. uint32 instance_extension_count = 0;
  116. FatalErrorIfFailed(vkEnumerateInstanceExtensionProperties(nullptr, &instance_extension_count, nullptr));
  117. Array<VkExtensionProperties> instance_extensions;
  118. instance_extensions.resize(instance_extension_count);
  119. FatalErrorIfFailed(vkEnumerateInstanceExtensionProperties(nullptr, &instance_extension_count, instance_extensions.data()));
  120. // Query supported validation layers
  121. uint32 validation_layer_count;
  122. vkEnumerateInstanceLayerProperties(&validation_layer_count, nullptr);
  123. Array<VkLayerProperties> validation_layers(validation_layer_count);
  124. vkEnumerateInstanceLayerProperties(&validation_layer_count, validation_layers.data());
  125. // Create Vulkan instance
  126. VkInstanceCreateInfo instance_create_info = {};
  127. instance_create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
  128. #ifdef JPH_PLATFORM_MACOS
  129. instance_create_info.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
  130. #endif
  131. #ifdef JPH_DEBUG
  132. // Enable validation layer if supported
  133. const char *desired_validation_layers[] = { "VK_LAYER_KHRONOS_validation" };
  134. for (const VkLayerProperties &p : validation_layers)
  135. if (strcmp(desired_validation_layers[0], p.layerName) == 0)
  136. {
  137. instance_create_info.enabledLayerCount = 1;
  138. instance_create_info.ppEnabledLayerNames = desired_validation_layers;
  139. break;
  140. }
  141. // Setup debug messenger callback if the extension is supported
  142. VkDebugUtilsMessengerCreateInfoEXT messenger_create_info = {};
  143. for (const VkExtensionProperties &ext : instance_extensions)
  144. if (strcmp(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, ext.extensionName) == 0)
  145. {
  146. messenger_create_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
  147. messenger_create_info.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
  148. messenger_create_info.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_DEVICE_ADDRESS_BINDING_BIT_EXT;
  149. messenger_create_info.pfnUserCallback = sVulkanDebugCallback;
  150. instance_create_info.pNext = &messenger_create_info;
  151. required_instance_extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
  152. break;
  153. }
  154. #endif
  155. instance_create_info.enabledExtensionCount = (uint32)required_instance_extensions.size();
  156. instance_create_info.ppEnabledExtensionNames = required_instance_extensions.data();
  157. FatalErrorIfFailed(vkCreateInstance(&instance_create_info, nullptr, &mInstance));
  158. #ifdef JPH_DEBUG
  159. // Finalize debug messenger callback
  160. PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT = (PFN_vkCreateDebugUtilsMessengerEXT)(std::uintptr_t)vkGetInstanceProcAddr(mInstance, "vkCreateDebugUtilsMessengerEXT");
  161. if (vkCreateDebugUtilsMessengerEXT != nullptr)
  162. FatalErrorIfFailed(vkCreateDebugUtilsMessengerEXT(mInstance, &messenger_create_info, nullptr, &mDebugMessenger));
  163. #endif
  164. // Create surface
  165. #ifdef JPH_PLATFORM_WINDOWS
  166. VkWin32SurfaceCreateInfoKHR surface_create_info = {};
  167. surface_create_info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
  168. surface_create_info.hwnd = static_cast<ApplicationWindowWin *>(mWindow)->GetWindowHandle();
  169. surface_create_info.hinstance = GetModuleHandle(nullptr);
  170. FatalErrorIfFailed(vkCreateWin32SurfaceKHR(mInstance, &surface_create_info, nullptr, &mSurface));
  171. #elif defined(JPH_PLATFORM_LINUX)
  172. VkXlibSurfaceCreateInfoKHR surface_create_info = {};
  173. surface_create_info.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
  174. surface_create_info.dpy = static_cast<ApplicationWindowLinux *>(mWindow)->GetDisplay();
  175. surface_create_info.window = static_cast<ApplicationWindowLinux *>(mWindow)->GetWindow();
  176. FatalErrorIfFailed(vkCreateXlibSurfaceKHR(mInstance, &surface_create_info, nullptr, &mSurface));
  177. #elif defined(JPH_PLATFORM_MACOS)
  178. VkMetalSurfaceCreateInfoEXT surface_create_info = {};
  179. surface_create_info.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT;
  180. surface_create_info.pNext = nullptr;
  181. surface_create_info.pLayer = static_cast<ApplicationWindowMacOS *>(mWindow)->GetMetalLayer();
  182. FatalErrorIfFailed(vkCreateMetalSurfaceEXT(mInstance, &surface_create_info, nullptr, &mSurface));
  183. #endif
  184. // Select device
  185. uint32 device_count = 0;
  186. FatalErrorIfFailed(vkEnumeratePhysicalDevices(mInstance, &device_count, nullptr));
  187. Array<VkPhysicalDevice> devices;
  188. devices.resize(device_count);
  189. FatalErrorIfFailed(vkEnumeratePhysicalDevices(mInstance, &device_count, devices.data()));
  190. struct Device
  191. {
  192. VkPhysicalDevice mPhysicalDevice;
  193. String mName;
  194. VkSurfaceFormatKHR mFormat;
  195. uint32 mGraphicsQueueIndex;
  196. uint32 mPresentQueueIndex;
  197. int mScore;
  198. };
  199. Array<Device> available_devices;
  200. for (VkPhysicalDevice device : devices)
  201. {
  202. // Get device properties
  203. VkPhysicalDeviceProperties properties;
  204. vkGetPhysicalDeviceProperties(device, &properties);
  205. // Test if it is an appropriate type
  206. int score = 0;
  207. switch (properties.deviceType)
  208. {
  209. case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
  210. score = 30;
  211. break;
  212. case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
  213. score = 20;
  214. break;
  215. case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
  216. score = 10;
  217. break;
  218. case VK_PHYSICAL_DEVICE_TYPE_CPU:
  219. score = 5;
  220. break;
  221. case VK_PHYSICAL_DEVICE_TYPE_OTHER:
  222. case VK_PHYSICAL_DEVICE_TYPE_MAX_ENUM:
  223. continue;
  224. }
  225. // Check if the device supports all our required extensions
  226. uint32 device_extension_count;
  227. vkEnumerateDeviceExtensionProperties(device, nullptr, &device_extension_count, nullptr);
  228. Array<VkExtensionProperties> available_extensions;
  229. available_extensions.resize(device_extension_count);
  230. vkEnumerateDeviceExtensionProperties(device, nullptr, &device_extension_count, available_extensions.data());
  231. int found_extensions = 0;
  232. for (const char *required_device_extension : required_device_extensions)
  233. for (const VkExtensionProperties &ext : available_extensions)
  234. if (strcmp(required_device_extension, ext.extensionName) == 0)
  235. {
  236. found_extensions++;
  237. break;
  238. }
  239. if (found_extensions != int(required_device_extensions.size()))
  240. continue;
  241. // Find the right queues
  242. uint32 queue_family_count = 0;
  243. vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_family_count, nullptr);
  244. Array<VkQueueFamilyProperties> queue_families;
  245. queue_families.resize(queue_family_count);
  246. vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_family_count, queue_families.data());
  247. uint32 graphics_queue = ~uint32(0);
  248. uint32 present_queue = ~uint32(0);
  249. for (uint32 i = 0; i < uint32(queue_families.size()); ++i)
  250. {
  251. if (queue_families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
  252. graphics_queue = i;
  253. VkBool32 present_support = false;
  254. vkGetPhysicalDeviceSurfaceSupportKHR(device, i, mSurface, &present_support);
  255. if (present_support)
  256. present_queue = i;
  257. if (graphics_queue != ~uint32(0) && present_queue != ~uint32(0))
  258. break;
  259. }
  260. if (graphics_queue == ~uint32(0) || present_queue == ~uint32(0))
  261. continue;
  262. // Select surface format
  263. VkSurfaceFormatKHR selected_format = SelectFormat(device);
  264. if (selected_format.format == VK_FORMAT_UNDEFINED)
  265. continue;
  266. // Add the device
  267. available_devices.push_back({ device, properties.deviceName, selected_format, graphics_queue, present_queue, score });
  268. }
  269. if (available_devices.empty())
  270. FatalError("No Vulkan device found!");
  271. QuickSort(available_devices.begin(), available_devices.end(), [](const Device &inLHS, const Device &inRHS) {
  272. return inLHS.mScore > inRHS.mScore;
  273. });
  274. const Device &selected_device = available_devices[0];
  275. Trace("Selected device: %s", selected_device.mName.c_str());
  276. mPhysicalDevice = selected_device.mPhysicalDevice;
  277. // Get memory properties
  278. vkGetPhysicalDeviceMemoryProperties(mPhysicalDevice, &mMemoryProperties);
  279. // Get features
  280. VkPhysicalDeviceFeatures physical_device_features = {};
  281. vkGetPhysicalDeviceFeatures(mPhysicalDevice, &physical_device_features);
  282. // Create device
  283. float queue_priority = 1.0f;
  284. VkDeviceQueueCreateInfo queue_create_info[2] = {};
  285. for (size_t i = 0; i < std::size(queue_create_info); ++i)
  286. {
  287. queue_create_info[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
  288. queue_create_info[i].queueCount = 1;
  289. queue_create_info[i].pQueuePriorities = &queue_priority;
  290. }
  291. queue_create_info[0].queueFamilyIndex = selected_device.mGraphicsQueueIndex;
  292. queue_create_info[1].queueFamilyIndex = selected_device.mPresentQueueIndex;
  293. VkPhysicalDeviceFeatures device_features = {};
  294. if (!physical_device_features.fillModeNonSolid)
  295. FatalError("fillModeNonSolid not supported!");
  296. device_features.fillModeNonSolid = VK_TRUE;
  297. VkDeviceCreateInfo device_create_info = {};
  298. device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
  299. device_create_info.queueCreateInfoCount = selected_device.mGraphicsQueueIndex != selected_device.mPresentQueueIndex? 2 : 1;
  300. device_create_info.pQueueCreateInfos = queue_create_info;
  301. device_create_info.enabledLayerCount = instance_create_info.enabledLayerCount;
  302. device_create_info.ppEnabledLayerNames = instance_create_info.ppEnabledLayerNames;
  303. device_create_info.enabledExtensionCount = uint32(required_device_extensions.size());
  304. device_create_info.ppEnabledExtensionNames = required_device_extensions.data();
  305. device_create_info.pEnabledFeatures = &device_features;
  306. FatalErrorIfFailed(vkCreateDevice(selected_device.mPhysicalDevice, &device_create_info, nullptr, &mDevice));
  307. // Get the queues
  308. mGraphicsQueueIndex = selected_device.mGraphicsQueueIndex;
  309. mPresentQueueIndex = selected_device.mPresentQueueIndex;
  310. vkGetDeviceQueue(mDevice, mGraphicsQueueIndex, 0, &mGraphicsQueue);
  311. vkGetDeviceQueue(mDevice, mPresentQueueIndex, 0, &mPresentQueue);
  312. VkCommandPoolCreateInfo pool_info = {};
  313. pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
  314. pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
  315. pool_info.queueFamilyIndex = selected_device.mGraphicsQueueIndex;
  316. FatalErrorIfFailed(vkCreateCommandPool(mDevice, &pool_info, nullptr, &mCommandPool));
  317. VkCommandBufferAllocateInfo command_buffer_info = {};
  318. command_buffer_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
  319. command_buffer_info.commandPool = mCommandPool;
  320. command_buffer_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
  321. command_buffer_info.commandBufferCount = 1;
  322. for (uint32 i = 0; i < cFrameCount; ++i)
  323. FatalErrorIfFailed(vkAllocateCommandBuffers(mDevice, &command_buffer_info, &mCommandBuffers[i]));
  324. VkSemaphoreCreateInfo semaphore_info = {};
  325. semaphore_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
  326. for (uint32 i = 0; i < cFrameCount; ++i)
  327. {
  328. FatalErrorIfFailed(vkCreateSemaphore(mDevice, &semaphore_info, nullptr, &mImageAvailableSemaphores[i]));
  329. FatalErrorIfFailed(vkCreateSemaphore(mDevice, &semaphore_info, nullptr, &mRenderFinishedSemaphores[i]));
  330. }
  331. VkFenceCreateInfo fence_info = {};
  332. fence_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
  333. fence_info.flags = VK_FENCE_CREATE_SIGNALED_BIT;
  334. for (uint32 i = 0; i < cFrameCount; ++i)
  335. FatalErrorIfFailed(vkCreateFence(mDevice, &fence_info, nullptr, &mInFlightFences[i]));
  336. // Create constant buffer. One per frame to avoid overwriting the constant buffer while the GPU is still using it.
  337. for (uint n = 0; n < cFrameCount; ++n)
  338. {
  339. mVertexShaderConstantBufferProjection[n] = CreateConstantBuffer(sizeof(VertexShaderConstantBuffer));
  340. mVertexShaderConstantBufferOrtho[n] = CreateConstantBuffer(sizeof(VertexShaderConstantBuffer));
  341. mPixelShaderConstantBuffer[n] = CreateConstantBuffer(sizeof(PixelShaderConstantBuffer));
  342. }
  343. // Create descriptor set layout for the uniform buffers
  344. VkDescriptorSetLayoutBinding ubo_layout_binding[2] = {};
  345. ubo_layout_binding[0].binding = 0;
  346. ubo_layout_binding[0].descriptorCount = 1;
  347. ubo_layout_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
  348. ubo_layout_binding[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
  349. ubo_layout_binding[1].binding = 1;
  350. ubo_layout_binding[1].descriptorCount = 1;
  351. ubo_layout_binding[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
  352. ubo_layout_binding[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
  353. VkDescriptorSetLayoutCreateInfo ubo_dsl = {};
  354. ubo_dsl.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
  355. ubo_dsl.bindingCount = std::size(ubo_layout_binding);
  356. ubo_dsl.pBindings = ubo_layout_binding;
  357. FatalErrorIfFailed(vkCreateDescriptorSetLayout(mDevice, &ubo_dsl, nullptr, &mDescriptorSetLayoutUBO));
  358. // Create descriptor set layout for the texture binding
  359. VkDescriptorSetLayoutBinding texture_layout_binding = {};
  360. texture_layout_binding.binding = 0;
  361. texture_layout_binding.descriptorCount = 1;
  362. texture_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
  363. texture_layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
  364. VkDescriptorSetLayoutCreateInfo texture_dsl = {};
  365. texture_dsl.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
  366. texture_dsl.bindingCount = 1;
  367. texture_dsl.pBindings = &texture_layout_binding;
  368. FatalErrorIfFailed(vkCreateDescriptorSetLayout(mDevice, &texture_dsl, nullptr, &mDescriptorSetLayoutTexture));
  369. // Create pipeline layout
  370. VkPipelineLayoutCreateInfo pipeline_layout = {};
  371. VkDescriptorSetLayout layout_handles[] = { mDescriptorSetLayoutUBO, mDescriptorSetLayoutTexture };
  372. pipeline_layout.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
  373. pipeline_layout.setLayoutCount = std::size(layout_handles);
  374. pipeline_layout.pSetLayouts = layout_handles;
  375. pipeline_layout.pushConstantRangeCount = 0;
  376. FatalErrorIfFailed(vkCreatePipelineLayout(mDevice, &pipeline_layout, nullptr, &mPipelineLayout));
  377. // Create descriptor pool
  378. VkDescriptorPoolSize descriptor_pool_sizes[] = {
  379. { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 128 },
  380. { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 128 },
  381. };
  382. VkDescriptorPoolCreateInfo descriptor_info = {};
  383. descriptor_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
  384. descriptor_info.poolSizeCount = std::size(descriptor_pool_sizes);
  385. descriptor_info.pPoolSizes = descriptor_pool_sizes;
  386. descriptor_info.maxSets = 256;
  387. FatalErrorIfFailed(vkCreateDescriptorPool(mDevice, &descriptor_info, nullptr, &mDescriptorPool));
  388. // Allocate descriptor sets for 3d rendering
  389. Array<VkDescriptorSetLayout> layouts(cFrameCount, mDescriptorSetLayoutUBO);
  390. VkDescriptorSetAllocateInfo descriptor_set_alloc_info = {};
  391. descriptor_set_alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
  392. descriptor_set_alloc_info.descriptorPool = mDescriptorPool;
  393. descriptor_set_alloc_info.descriptorSetCount = cFrameCount;
  394. descriptor_set_alloc_info.pSetLayouts = layouts.data();
  395. FatalErrorIfFailed(vkAllocateDescriptorSets(mDevice, &descriptor_set_alloc_info, mDescriptorSets));
  396. for (uint i = 0; i < cFrameCount; i++)
  397. {
  398. VkDescriptorBufferInfo vs_buffer_info = {};
  399. vs_buffer_info.buffer = mVertexShaderConstantBufferProjection[i]->GetBuffer();
  400. vs_buffer_info.range = sizeof(VertexShaderConstantBuffer);
  401. VkDescriptorBufferInfo ps_buffer_info = {};
  402. ps_buffer_info.buffer = mPixelShaderConstantBuffer[i]->GetBuffer();
  403. ps_buffer_info.range = sizeof(PixelShaderConstantBuffer);
  404. VkWriteDescriptorSet descriptor_write[2] = {};
  405. descriptor_write[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
  406. descriptor_write[0].dstSet = mDescriptorSets[i];
  407. descriptor_write[0].dstBinding = 0;
  408. descriptor_write[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
  409. descriptor_write[0].descriptorCount = 1;
  410. descriptor_write[0].pBufferInfo = &vs_buffer_info;
  411. descriptor_write[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
  412. descriptor_write[1].dstSet = mDescriptorSets[i];
  413. descriptor_write[1].dstBinding = 1;
  414. descriptor_write[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
  415. descriptor_write[1].descriptorCount = 1;
  416. descriptor_write[1].pBufferInfo = &ps_buffer_info;
  417. vkUpdateDescriptorSets(mDevice, 2, descriptor_write, 0, nullptr);
  418. }
  419. // Allocate descriptor sets for 2d rendering
  420. FatalErrorIfFailed(vkAllocateDescriptorSets(mDevice, &descriptor_set_alloc_info, mDescriptorSetsOrtho));
  421. for (uint i = 0; i < cFrameCount; i++)
  422. {
  423. VkDescriptorBufferInfo vs_buffer_info = {};
  424. vs_buffer_info.buffer = mVertexShaderConstantBufferOrtho[i]->GetBuffer();
  425. vs_buffer_info.range = sizeof(VertexShaderConstantBuffer);
  426. VkWriteDescriptorSet descriptor_write = {};
  427. descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
  428. descriptor_write.dstSet = mDescriptorSetsOrtho[i];
  429. descriptor_write.dstBinding = 0;
  430. descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
  431. descriptor_write.descriptorCount = 1;
  432. descriptor_write.pBufferInfo = &vs_buffer_info;
  433. vkUpdateDescriptorSets(mDevice, 1, &descriptor_write, 0, nullptr);
  434. }
  435. // Create regular texture sampler
  436. VkSamplerCreateInfo sampler_info = {};
  437. sampler_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
  438. sampler_info.magFilter = VK_FILTER_LINEAR;
  439. sampler_info.minFilter = VK_FILTER_LINEAR;
  440. sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
  441. sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
  442. sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
  443. sampler_info.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
  444. sampler_info.unnormalizedCoordinates = VK_FALSE;
  445. sampler_info.minLod = 0.0f;
  446. sampler_info.maxLod = VK_LOD_CLAMP_NONE;
  447. sampler_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
  448. FatalErrorIfFailed(vkCreateSampler(mDevice, &sampler_info, nullptr, &mTextureSamplerRepeat));
  449. // Create sampler for shadow maps
  450. sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
  451. sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
  452. sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
  453. FatalErrorIfFailed(vkCreateSampler(mDevice, &sampler_info, nullptr, &mTextureSamplerShadow));
  454. {
  455. // Create shadow render pass
  456. VkAttachmentDescription shadowmap_attachment = {};
  457. shadowmap_attachment.format = FindDepthFormat();
  458. shadowmap_attachment.samples = VK_SAMPLE_COUNT_1_BIT;
  459. shadowmap_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
  460. shadowmap_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
  461. shadowmap_attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
  462. shadowmap_attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
  463. shadowmap_attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
  464. shadowmap_attachment.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
  465. VkAttachmentReference shadowmap_attachment_ref = {};
  466. shadowmap_attachment_ref.attachment = 0;
  467. shadowmap_attachment_ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
  468. VkSubpassDescription subpass_shadow = {};
  469. subpass_shadow.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
  470. subpass_shadow.pDepthStencilAttachment = &shadowmap_attachment_ref;
  471. VkSubpassDependency dependencies_shadow = {};
  472. dependencies_shadow.srcSubpass = VK_SUBPASS_EXTERNAL;
  473. dependencies_shadow.dstSubpass = 0;
  474. dependencies_shadow.srcStageMask = VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
  475. dependencies_shadow.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
  476. dependencies_shadow.dstStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
  477. dependencies_shadow.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
  478. VkRenderPassCreateInfo render_pass_shadow = {};
  479. render_pass_shadow.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
  480. render_pass_shadow.attachmentCount = 1;
  481. render_pass_shadow.pAttachments = &shadowmap_attachment;
  482. render_pass_shadow.subpassCount = 1;
  483. render_pass_shadow.pSubpasses = &subpass_shadow;
  484. render_pass_shadow.dependencyCount = 1;
  485. render_pass_shadow.pDependencies = &dependencies_shadow;
  486. FatalErrorIfFailed(vkCreateRenderPass(mDevice, &render_pass_shadow, nullptr, &mRenderPassShadow));
  487. }
  488. // Create depth only texture (no color buffer, as seen from light)
  489. mShadowMap = new TextureVK(this, cShadowMapSize, cShadowMapSize);
  490. // Create frame buffer for the shadow pass
  491. VkImageView attachments[] = { mShadowMap->GetImageView() };
  492. VkFramebufferCreateInfo frame_buffer_info = {};
  493. frame_buffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
  494. frame_buffer_info.renderPass = mRenderPassShadow;
  495. frame_buffer_info.attachmentCount = std::size(attachments);
  496. frame_buffer_info.pAttachments = attachments;
  497. frame_buffer_info.width = cShadowMapSize;
  498. frame_buffer_info.height = cShadowMapSize;
  499. frame_buffer_info.layers = 1;
  500. FatalErrorIfFailed(vkCreateFramebuffer(mDevice, &frame_buffer_info, nullptr, &mShadowFrameBuffer));
  501. {
  502. // Create normal render pass
  503. VkAttachmentDescription attachments_normal[2] = {};
  504. VkAttachmentDescription &color_attachment = attachments_normal[0];
  505. color_attachment.format = selected_device.mFormat.format;
  506. color_attachment.samples = VK_SAMPLE_COUNT_1_BIT;
  507. color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
  508. color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
  509. color_attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
  510. color_attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
  511. color_attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
  512. color_attachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
  513. VkAttachmentReference color_attachment_ref = {};
  514. color_attachment_ref.attachment = 0;
  515. color_attachment_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
  516. VkAttachmentDescription &depth_attachment = attachments_normal[1];
  517. depth_attachment.format = FindDepthFormat();
  518. depth_attachment.samples = VK_SAMPLE_COUNT_1_BIT;
  519. depth_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
  520. depth_attachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
  521. depth_attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
  522. depth_attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
  523. depth_attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
  524. depth_attachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
  525. VkAttachmentReference depth_attachment_ref = {};
  526. depth_attachment_ref.attachment = 1;
  527. depth_attachment_ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
  528. VkSubpassDescription subpass_normal = {};
  529. subpass_normal.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
  530. subpass_normal.colorAttachmentCount = 1;
  531. subpass_normal.pColorAttachments = &color_attachment_ref;
  532. subpass_normal.pDepthStencilAttachment = &depth_attachment_ref;
  533. VkSubpassDependency dependencies_normal = {};
  534. dependencies_normal.srcSubpass = VK_SUBPASS_EXTERNAL;
  535. dependencies_normal.dstSubpass = 0;
  536. dependencies_normal.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
  537. dependencies_normal.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
  538. dependencies_normal.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
  539. dependencies_normal.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT;
  540. VkRenderPassCreateInfo render_pass_normal = {};
  541. render_pass_normal.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
  542. render_pass_normal.attachmentCount = std::size(attachments_normal);
  543. render_pass_normal.pAttachments = attachments_normal;
  544. render_pass_normal.subpassCount = 1;
  545. render_pass_normal.pSubpasses = &subpass_normal;
  546. render_pass_normal.dependencyCount = 1;
  547. render_pass_normal.pDependencies = &dependencies_normal;
  548. FatalErrorIfFailed(vkCreateRenderPass(mDevice, &render_pass_normal, nullptr, &mRenderPass));
  549. }
  550. // Create the swap chain
  551. CreateSwapChain(mPhysicalDevice);
  552. }
  553. VkSurfaceFormatKHR RendererVK::SelectFormat(VkPhysicalDevice inDevice)
  554. {
  555. uint32 format_count;
  556. vkGetPhysicalDeviceSurfaceFormatsKHR(inDevice, mSurface, &format_count, nullptr);
  557. if (format_count == 0)
  558. return { VK_FORMAT_UNDEFINED, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR };
  559. Array<VkSurfaceFormatKHR> formats;
  560. formats.resize(format_count);
  561. vkGetPhysicalDeviceSurfaceFormatsKHR(inDevice, mSurface, &format_count, formats.data());
  562. // Select BGRA8 UNORM format if available, otherwise the 1st format
  563. for (const VkSurfaceFormatKHR &format : formats)
  564. if (format.format == VK_FORMAT_B8G8R8A8_UNORM && format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
  565. return format;
  566. return formats[0];
  567. }
  568. VkFormat RendererVK::FindDepthFormat()
  569. {
  570. VkFormat candidates[] = { VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT };
  571. for (VkFormat format : candidates)
  572. {
  573. VkFormatProperties props;
  574. vkGetPhysicalDeviceFormatProperties(mPhysicalDevice, format, &props);
  575. if ((props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) == VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
  576. return format;
  577. }
  578. FatalError("Failed to find format!");
  579. }
  580. void RendererVK::CreateSwapChain(VkPhysicalDevice inDevice)
  581. {
  582. // Select the format
  583. VkSurfaceFormatKHR format = SelectFormat(inDevice);
  584. mSwapChainImageFormat = format.format;
  585. // Determine swap chain extent
  586. VkSurfaceCapabilitiesKHR capabilities;
  587. vkGetPhysicalDeviceSurfaceCapabilitiesKHR(inDevice, mSurface, &capabilities);
  588. mSwapChainExtent = capabilities.currentExtent;
  589. if (mSwapChainExtent.width == UINT32_MAX || mSwapChainExtent.height == UINT32_MAX)
  590. mSwapChainExtent = { uint32(mWindow->GetWindowWidth()), uint32(mWindow->GetWindowHeight()) };
  591. mSwapChainExtent.width = Clamp(mSwapChainExtent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width);
  592. mSwapChainExtent.height = Clamp(mSwapChainExtent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height);
  593. // Early out if our window has been minimized
  594. if (mSwapChainExtent.width == 0 || mSwapChainExtent.height == 0)
  595. return;
  596. // Create the swap chain
  597. uint32 desired_image_count = max(min(capabilities.minImageCount + 1, capabilities.maxImageCount), capabilities.minImageCount);
  598. VkSwapchainCreateInfoKHR swapchain_create_info = {};
  599. swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
  600. swapchain_create_info.surface = mSurface;
  601. swapchain_create_info.minImageCount = desired_image_count;
  602. swapchain_create_info.imageFormat = format.format;
  603. swapchain_create_info.imageColorSpace = format.colorSpace;
  604. swapchain_create_info.imageExtent = mSwapChainExtent;
  605. swapchain_create_info.imageArrayLayers = 1;
  606. swapchain_create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
  607. uint32 queue_family_indices[] = { mGraphicsQueueIndex, mPresentQueueIndex };
  608. if (mGraphicsQueueIndex != mPresentQueueIndex)
  609. {
  610. swapchain_create_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
  611. swapchain_create_info.queueFamilyIndexCount = 2;
  612. swapchain_create_info.pQueueFamilyIndices = queue_family_indices;
  613. }
  614. else
  615. {
  616. swapchain_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
  617. }
  618. swapchain_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
  619. swapchain_create_info.preTransform = capabilities.currentTransform;
  620. swapchain_create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
  621. swapchain_create_info.presentMode = VK_PRESENT_MODE_FIFO_KHR;
  622. swapchain_create_info.clipped = VK_TRUE;
  623. FatalErrorIfFailed(vkCreateSwapchainKHR(mDevice, &swapchain_create_info, nullptr, &mSwapChain));
  624. // Get the actual swap chain image count
  625. uint32 image_count;
  626. FatalErrorIfFailed(vkGetSwapchainImagesKHR(mDevice, mSwapChain, &image_count, nullptr));
  627. // Get the swap chain images
  628. mSwapChainImages.resize(image_count);
  629. FatalErrorIfFailed(vkGetSwapchainImagesKHR(mDevice, mSwapChain, &image_count, mSwapChainImages.data()));
  630. // Create image views
  631. mSwapChainImageViews.resize(image_count);
  632. for (uint32 i = 0; i < image_count; ++i)
  633. mSwapChainImageViews[i] = CreateImageView(mSwapChainImages[i], mSwapChainImageFormat, VK_IMAGE_ASPECT_COLOR_BIT);
  634. // Create depth buffer
  635. VkFormat depth_format = FindDepthFormat();
  636. VkImageUsageFlags depth_usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
  637. VkMemoryPropertyFlags depth_memory_properties = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
  638. // Test and utilize support for transient memory for the depth buffer
  639. VkImageFormatProperties depth_transient_properties = {};
  640. VkResult depth_transient_support = vkGetPhysicalDeviceImageFormatProperties(mPhysicalDevice, depth_format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, depth_usage | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, 0, &depth_transient_properties);
  641. if (depth_transient_support == VK_SUCCESS)
  642. {
  643. depth_usage |= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
  644. // Test and utilize lazily allocated memory for the depth buffer
  645. for (size_t i = 0; i < mMemoryProperties.memoryTypeCount; i++)
  646. if (mMemoryProperties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT)
  647. {
  648. depth_memory_properties = VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT;
  649. break;
  650. }
  651. }
  652. CreateImage(mSwapChainExtent.width, mSwapChainExtent.height, depth_format, VK_IMAGE_TILING_OPTIMAL, depth_usage, depth_memory_properties, mDepthImage, mDepthImageMemory);
  653. mDepthImageView = CreateImageView(mDepthImage, depth_format, VK_IMAGE_ASPECT_DEPTH_BIT);
  654. // Create frame buffers for the normal pass
  655. mSwapChainFramebuffers.resize(image_count);
  656. for (size_t i = 0; i < mSwapChainFramebuffers.size(); i++)
  657. {
  658. VkImageView attachments[] = { mSwapChainImageViews[i], mDepthImageView };
  659. VkFramebufferCreateInfo frame_buffer_info = {};
  660. frame_buffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
  661. frame_buffer_info.renderPass = mRenderPass;
  662. frame_buffer_info.attachmentCount = std::size(attachments);
  663. frame_buffer_info.pAttachments = attachments;
  664. frame_buffer_info.width = mSwapChainExtent.width;
  665. frame_buffer_info.height = mSwapChainExtent.height;
  666. frame_buffer_info.layers = 1;
  667. FatalErrorIfFailed(vkCreateFramebuffer(mDevice, &frame_buffer_info, nullptr, &mSwapChainFramebuffers[i]));
  668. }
  669. }
  670. void RendererVK::DestroySwapChain()
  671. {
  672. // Destroy depth buffer
  673. if (mDepthImageView != VK_NULL_HANDLE)
  674. {
  675. vkDestroyImageView(mDevice, mDepthImageView, nullptr);
  676. DestroyImage(mDepthImage, mDepthImageMemory);
  677. }
  678. for (VkFramebuffer frame_buffer : mSwapChainFramebuffers)
  679. vkDestroyFramebuffer(mDevice, frame_buffer, nullptr);
  680. mSwapChainFramebuffers.clear();
  681. for (VkImageView view : mSwapChainImageViews)
  682. vkDestroyImageView(mDevice, view, nullptr);
  683. mSwapChainImageViews.clear();
  684. if (mSwapChain != VK_NULL_HANDLE)
  685. {
  686. vkDestroySwapchainKHR(mDevice, mSwapChain, nullptr);
  687. mSwapChain = VK_NULL_HANDLE;
  688. }
  689. }
  690. void RendererVK::OnWindowResize()
  691. {
  692. vkDeviceWaitIdle(mDevice);
  693. DestroySwapChain();
  694. CreateSwapChain(mPhysicalDevice);
  695. }
  696. void RendererVK::BeginFrame(const CameraState &inCamera, float inWorldScale)
  697. {
  698. JPH_PROFILE_FUNCTION();
  699. Renderer::BeginFrame(inCamera, inWorldScale);
  700. // If we have no swap chain, bail out
  701. if (mSwapChain == VK_NULL_HANDLE)
  702. return;
  703. // Update frame index
  704. mFrameIndex = (mFrameIndex + 1) % cFrameCount;
  705. // Wait for this frame to complete
  706. vkWaitForFences(mDevice, 1, &mInFlightFences[mFrameIndex], VK_TRUE, UINT64_MAX);
  707. VkResult result = mSubOptimalSwapChain? VK_ERROR_OUT_OF_DATE_KHR : vkAcquireNextImageKHR(mDevice, mSwapChain, UINT64_MAX, mImageAvailableSemaphores[mFrameIndex], VK_NULL_HANDLE, &mImageIndex);
  708. if (result == VK_ERROR_OUT_OF_DATE_KHR)
  709. {
  710. vkDeviceWaitIdle(mDevice);
  711. DestroySwapChain();
  712. CreateSwapChain(mPhysicalDevice);
  713. if (mSwapChain == VK_NULL_HANDLE)
  714. return;
  715. result = vkAcquireNextImageKHR(mDevice, mSwapChain, UINT64_MAX, mImageAvailableSemaphores[mFrameIndex], VK_NULL_HANDLE, &mImageIndex);
  716. mSubOptimalSwapChain = false;
  717. }
  718. else if (result == VK_SUBOPTIMAL_KHR)
  719. {
  720. // Render this frame with the suboptimal swap chain as we've already acquired an image
  721. mSubOptimalSwapChain = true;
  722. result = VK_SUCCESS;
  723. }
  724. FatalErrorIfFailed(result);
  725. // Free buffers that weren't used this frame
  726. for (BufferCache::value_type &vt : mBufferCache)
  727. for (BufferVK &bvk : vt.second)
  728. FreeBufferInternal(bvk);
  729. mBufferCache.clear();
  730. // Recycle the buffers that were freed
  731. mBufferCache.swap(mFreedBuffers[mFrameIndex]);
  732. vkResetFences(mDevice, 1, &mInFlightFences[mFrameIndex]);
  733. VkCommandBuffer command_buffer = GetCommandBuffer();
  734. FatalErrorIfFailed(vkResetCommandBuffer(command_buffer, 0));
  735. VkCommandBufferBeginInfo command_buffer_begin_info = {};
  736. command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
  737. command_buffer_begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
  738. FatalErrorIfFailed(vkBeginCommandBuffer(command_buffer, &command_buffer_begin_info));
  739. // Begin the shadow pass
  740. VkClearValue clear_value;
  741. clear_value.depthStencil = { 0.0f, 0 };
  742. VkRenderPassBeginInfo render_pass_begin_info = {};
  743. render_pass_begin_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
  744. render_pass_begin_info.renderPass = mRenderPassShadow;
  745. render_pass_begin_info.framebuffer = mShadowFrameBuffer;
  746. render_pass_begin_info.renderArea.extent = { cShadowMapSize, cShadowMapSize };
  747. render_pass_begin_info.clearValueCount = 1;
  748. render_pass_begin_info.pClearValues = &clear_value;
  749. vkCmdBeginRenderPass(command_buffer, &render_pass_begin_info, VK_SUBPASS_CONTENTS_INLINE);
  750. // Set constants for vertex shader in projection mode
  751. VertexShaderConstantBuffer *vs = mVertexShaderConstantBufferProjection[mFrameIndex]->Map<VertexShaderConstantBuffer>();
  752. *vs = mVSBuffer;
  753. mVertexShaderConstantBufferProjection[mFrameIndex]->Unmap();
  754. // Set constants for vertex shader in ortho mode
  755. vs = mVertexShaderConstantBufferOrtho[mFrameIndex]->Map<VertexShaderConstantBuffer>();
  756. *vs = mVSBufferOrtho;
  757. mVertexShaderConstantBufferOrtho[mFrameIndex]->Unmap();
  758. // Set constants for pixel shader
  759. PixelShaderConstantBuffer *ps = mPixelShaderConstantBuffer[mFrameIndex]->Map<PixelShaderConstantBuffer>();
  760. *ps = mPSBuffer;
  761. mPixelShaderConstantBuffer[mFrameIndex]->Unmap();
  762. // Set the view port and scissor rect to the shadow map size
  763. UpdateViewPortAndScissorRect(cShadowMapSize, cShadowMapSize);
  764. // Switch to 3d projection mode
  765. SetProjectionMode();
  766. }
  767. void RendererVK::EndShadowPass()
  768. {
  769. VkCommandBuffer command_buffer = GetCommandBuffer();
  770. // End the shadow pass
  771. vkCmdEndRenderPass(command_buffer);
  772. // Begin the normal render pass
  773. VkClearValue clear_values[2];
  774. clear_values[0].color = {{ 0.098f, 0.098f, 0.439f, 1.000f }};
  775. clear_values[1].depthStencil = { 0.0f, 0 }; // Reverse-Z clears to 0
  776. VkRenderPassBeginInfo render_pass_begin_info = {};
  777. render_pass_begin_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
  778. render_pass_begin_info.renderPass = mRenderPass;
  779. JPH_ASSERT(mImageIndex < mSwapChainFramebuffers.size());
  780. render_pass_begin_info.framebuffer = mSwapChainFramebuffers[mImageIndex];
  781. render_pass_begin_info.renderArea.extent = mSwapChainExtent;
  782. render_pass_begin_info.clearValueCount = std::size(clear_values);
  783. render_pass_begin_info.pClearValues = clear_values;
  784. vkCmdBeginRenderPass(command_buffer, &render_pass_begin_info, VK_SUBPASS_CONTENTS_INLINE);
  785. // Set the view port and scissor rect to the screen size
  786. UpdateViewPortAndScissorRect(mSwapChainExtent.width, mSwapChainExtent.height);
  787. }
  788. void RendererVK::EndFrame()
  789. {
  790. JPH_PROFILE_FUNCTION();
  791. // If we have no swap chain, bail out
  792. if (mSwapChain == VK_NULL_HANDLE)
  793. {
  794. Renderer::EndFrame();
  795. return;
  796. }
  797. VkCommandBuffer command_buffer = GetCommandBuffer();
  798. vkCmdEndRenderPass(command_buffer);
  799. FatalErrorIfFailed(vkEndCommandBuffer(command_buffer));
  800. VkSemaphore wait_semaphores[] = { mImageAvailableSemaphores[mFrameIndex] };
  801. VkSemaphore signal_semaphores[] = { mRenderFinishedSemaphores[mFrameIndex] };
  802. VkPipelineStageFlags wait_stages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
  803. VkSubmitInfo submit_info = {};
  804. submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
  805. submit_info.waitSemaphoreCount = 1;
  806. submit_info.pWaitSemaphores = wait_semaphores;
  807. submit_info.pWaitDstStageMask = wait_stages;
  808. submit_info.commandBufferCount = 1;
  809. submit_info.pCommandBuffers = &command_buffer;
  810. submit_info.signalSemaphoreCount = 1;
  811. submit_info.pSignalSemaphores = signal_semaphores;
  812. FatalErrorIfFailed(vkQueueSubmit(mGraphicsQueue, 1, &submit_info, mInFlightFences[mFrameIndex]));
  813. VkSwapchainKHR swap_chains[] = { mSwapChain };
  814. VkPresentInfoKHR present_info = {};
  815. present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
  816. present_info.waitSemaphoreCount = 1;
  817. present_info.pWaitSemaphores = signal_semaphores;
  818. present_info.swapchainCount = 1;
  819. present_info.pSwapchains = swap_chains;
  820. present_info.pImageIndices = &mImageIndex;
  821. vkQueuePresentKHR(mPresentQueue, &present_info);
  822. Renderer::EndFrame();
  823. }
  824. void RendererVK::SetProjectionMode()
  825. {
  826. JPH_ASSERT(mInFrame);
  827. // Bind descriptor set for 3d rendering
  828. vkCmdBindDescriptorSets(GetCommandBuffer(), VK_PIPELINE_BIND_POINT_GRAPHICS, mPipelineLayout, 0, 1, &mDescriptorSets[mFrameIndex], 0, nullptr);
  829. }
  830. void RendererVK::SetOrthoMode()
  831. {
  832. JPH_ASSERT(mInFrame);
  833. // Bind descriptor set for 2d rendering
  834. vkCmdBindDescriptorSets(GetCommandBuffer(), VK_PIPELINE_BIND_POINT_GRAPHICS, mPipelineLayout, 0, 1, &mDescriptorSetsOrtho[mFrameIndex], 0, nullptr);
  835. }
  836. Ref<Texture> RendererVK::CreateTexture(const Surface *inSurface)
  837. {
  838. return new TextureVK(this, inSurface);
  839. }
  840. Ref<VertexShader> RendererVK::CreateVertexShader(const char *inName)
  841. {
  842. Array<uint8> data = ReadData((String("Shaders/VK/") + inName + ".vert.spv").c_str());
  843. VkShaderModuleCreateInfo create_info = {};
  844. create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
  845. create_info.codeSize = data.size();
  846. create_info.pCode = reinterpret_cast<const uint32 *>(data.data());
  847. VkShaderModule shader_module;
  848. FatalErrorIfFailed(vkCreateShaderModule(mDevice, &create_info, nullptr, &shader_module));
  849. return new VertexShaderVK(mDevice, shader_module);
  850. }
  851. Ref<PixelShader> RendererVK::CreatePixelShader(const char *inName)
  852. {
  853. Array<uint8> data = ReadData((String("Shaders/VK/") + inName + ".frag.spv").c_str());
  854. VkShaderModuleCreateInfo create_info = {};
  855. create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
  856. create_info.codeSize = data.size();
  857. create_info.pCode = reinterpret_cast<const uint32 *>(data.data());
  858. VkShaderModule shader_module;
  859. FatalErrorIfFailed(vkCreateShaderModule(mDevice, &create_info, nullptr, &shader_module));
  860. return new PixelShaderVK(mDevice, shader_module);
  861. }
  862. unique_ptr<PipelineState> RendererVK::CreatePipelineState(const VertexShader *inVertexShader, const PipelineState::EInputDescription *inInputDescription, uint inInputDescriptionCount, const PixelShader *inPixelShader, PipelineState::EDrawPass inDrawPass, PipelineState::EFillMode inFillMode, PipelineState::ETopology inTopology, PipelineState::EDepthTest inDepthTest, PipelineState::EBlendMode inBlendMode, PipelineState::ECullMode inCullMode)
  863. {
  864. return make_unique<PipelineStateVK>(this, static_cast<const VertexShaderVK *>(inVertexShader), inInputDescription, inInputDescriptionCount, static_cast<const PixelShaderVK *>(inPixelShader), inDrawPass, inFillMode, inTopology, inDepthTest, inBlendMode, inCullMode);
  865. }
  866. RenderPrimitive *RendererVK::CreateRenderPrimitive(PipelineState::ETopology inType)
  867. {
  868. return new RenderPrimitiveVK(this);
  869. }
  870. RenderInstances *RendererVK::CreateRenderInstances()
  871. {
  872. return new RenderInstancesVK(this);
  873. }
  874. uint32 RendererVK::FindMemoryType(uint32 inTypeFilter, VkMemoryPropertyFlags inProperties)
  875. {
  876. for (uint32 i = 0; i < mMemoryProperties.memoryTypeCount; i++)
  877. if ((inTypeFilter & (1 << i))
  878. && (mMemoryProperties.memoryTypes[i].propertyFlags & inProperties) == inProperties)
  879. return i;
  880. FatalError("Failed to find memory type!");
  881. }
  882. void RendererVK::AllocateMemory(VkDeviceSize inSize, uint32 inMemoryTypeBits, VkMemoryPropertyFlags inProperties, VkDeviceMemory &outMemory)
  883. {
  884. VkMemoryAllocateInfo alloc_info = {};
  885. alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
  886. alloc_info.allocationSize = inSize;
  887. alloc_info.memoryTypeIndex = FindMemoryType(inMemoryTypeBits, inProperties);
  888. FatalErrorIfFailed(vkAllocateMemory(mDevice, &alloc_info, nullptr, &outMemory));
  889. // Track allocation
  890. ++mNumAllocations;
  891. mTotalAllocated += inSize;
  892. // Track max usage
  893. mMaxTotalAllocated = max(mMaxTotalAllocated, mTotalAllocated);
  894. mMaxNumAllocations = max(mMaxNumAllocations, mNumAllocations);
  895. }
  896. void RendererVK::FreeMemory(VkDeviceMemory inMemory, VkDeviceSize inSize)
  897. {
  898. vkFreeMemory(mDevice, inMemory, nullptr);
  899. // Track free
  900. --mNumAllocations;
  901. mTotalAllocated -= inSize;
  902. }
  903. void RendererVK::CreateBuffer(VkDeviceSize inSize, VkBufferUsageFlags inUsage, VkMemoryPropertyFlags inProperties, BufferVK &outBuffer)
  904. {
  905. // Check the cache
  906. BufferCache::iterator i = mBufferCache.find({ inSize, inUsage, inProperties });
  907. if (i != mBufferCache.end() && !i->second.empty())
  908. {
  909. outBuffer = i->second.back();
  910. i->second.pop_back();
  911. return;
  912. }
  913. // Create a new buffer
  914. outBuffer.mSize = inSize;
  915. outBuffer.mUsage = inUsage;
  916. outBuffer.mProperties = inProperties;
  917. VkBufferCreateInfo create_info = {};
  918. create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
  919. create_info.size = inSize;
  920. create_info.usage = inUsage;
  921. create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
  922. FatalErrorIfFailed(vkCreateBuffer(mDevice, &create_info, nullptr, &outBuffer.mBuffer));
  923. VkMemoryRequirements mem_requirements;
  924. vkGetBufferMemoryRequirements(mDevice, outBuffer.mBuffer, &mem_requirements);
  925. if (mem_requirements.size > cMaxAllocSize)
  926. {
  927. // Allocate block directly
  928. AllocateMemory(mem_requirements.size, mem_requirements.memoryTypeBits, inProperties, outBuffer.mMemory);
  929. outBuffer.mAllocatedSize = mem_requirements.size;
  930. outBuffer.mOffset = 0;
  931. }
  932. else
  933. {
  934. // Round allocation to the next power of 2 so that we can use a simple block based allocator
  935. outBuffer.mAllocatedSize = max(VkDeviceSize(GetNextPowerOf2(uint32(mem_requirements.size))), cMinAllocSize);
  936. // Ensure that we have memory available from the right pool
  937. Array<Memory> &mem_array = mMemoryCache[{ outBuffer.mAllocatedSize, outBuffer.mUsage, outBuffer.mProperties }];
  938. if (mem_array.empty())
  939. {
  940. // Allocate a bigger block
  941. VkDeviceMemory device_memory;
  942. AllocateMemory(cBlockSize, mem_requirements.memoryTypeBits, inProperties, device_memory);
  943. // Divide into sub blocks
  944. for (VkDeviceSize offset = 0; offset < cBlockSize; offset += outBuffer.mAllocatedSize)
  945. mem_array.push_back({ device_memory, offset });
  946. }
  947. // Claim memory from the pool
  948. Memory &memory = mem_array.back();
  949. outBuffer.mMemory = memory.mMemory;
  950. outBuffer.mOffset = memory.mOffset;
  951. mem_array.pop_back();
  952. }
  953. // Bind the memory to the buffer
  954. vkBindBufferMemory(mDevice, outBuffer.mBuffer, outBuffer.mMemory, outBuffer.mOffset);
  955. }
  956. VkCommandBuffer RendererVK::StartTempCommandBuffer()
  957. {
  958. VkCommandBufferAllocateInfo alloc_info = {};
  959. alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
  960. alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
  961. alloc_info.commandPool = mCommandPool;
  962. alloc_info.commandBufferCount = 1;
  963. VkCommandBuffer command_buffer;
  964. vkAllocateCommandBuffers(mDevice, &alloc_info, &command_buffer);
  965. VkCommandBufferBeginInfo begin_info = {};
  966. begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
  967. begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
  968. vkBeginCommandBuffer(command_buffer, &begin_info);
  969. return command_buffer;
  970. }
  971. void RendererVK::EndTempCommandBuffer(VkCommandBuffer inCommandBuffer)
  972. {
  973. vkEndCommandBuffer(inCommandBuffer);
  974. VkSubmitInfo submit_info = {};
  975. submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
  976. submit_info.commandBufferCount = 1;
  977. submit_info.pCommandBuffers = &inCommandBuffer;
  978. vkQueueSubmit(mGraphicsQueue, 1, &submit_info, VK_NULL_HANDLE);
  979. vkQueueWaitIdle(mGraphicsQueue); // Inefficient, but we only use this during initialization
  980. vkFreeCommandBuffers(mDevice, mCommandPool, 1, &inCommandBuffer);
  981. }
  982. void RendererVK::CopyBuffer(VkBuffer inSrc, VkBuffer inDst, VkDeviceSize inSize)
  983. {
  984. VkCommandBuffer command_buffer = StartTempCommandBuffer();
  985. VkBufferCopy region = {};
  986. region.size = inSize;
  987. vkCmdCopyBuffer(command_buffer, inSrc, inDst, 1, &region);
  988. EndTempCommandBuffer(command_buffer);
  989. }
  990. void RendererVK::CreateDeviceLocalBuffer(const void *inData, VkDeviceSize inSize, VkBufferUsageFlags inUsage, BufferVK &outBuffer)
  991. {
  992. BufferVK staging_buffer;
  993. CreateBuffer(inSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, staging_buffer);
  994. void *data;
  995. vkMapMemory(mDevice, staging_buffer.mMemory, staging_buffer.mOffset, inSize, 0, &data);
  996. memcpy(data, inData, (size_t)inSize);
  997. vkUnmapMemory(mDevice, staging_buffer.mMemory);
  998. CreateBuffer(inSize, inUsage | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, outBuffer);
  999. CopyBuffer(staging_buffer.mBuffer, outBuffer.mBuffer, inSize);
  1000. FreeBuffer(staging_buffer);
  1001. }
  1002. void RendererVK::FreeBuffer(BufferVK &ioBuffer)
  1003. {
  1004. if (ioBuffer.mBuffer != VK_NULL_HANDLE)
  1005. {
  1006. JPH_ASSERT(mFrameIndex < cFrameCount);
  1007. mFreedBuffers[mFrameIndex][{ ioBuffer.mSize, ioBuffer.mUsage, ioBuffer.mProperties }].push_back(ioBuffer);
  1008. }
  1009. }
  1010. void RendererVK::FreeBufferInternal(BufferVK &ioBuffer)
  1011. {
  1012. // Destroy the buffer
  1013. vkDestroyBuffer(mDevice, ioBuffer.mBuffer, nullptr);
  1014. ioBuffer.mBuffer = VK_NULL_HANDLE;
  1015. if (ioBuffer.mAllocatedSize > cMaxAllocSize)
  1016. FreeMemory(ioBuffer.mMemory, ioBuffer.mAllocatedSize);
  1017. else
  1018. mMemoryCache[{ ioBuffer.mAllocatedSize, ioBuffer.mUsage, ioBuffer.mProperties }].push_back({ ioBuffer.mMemory, ioBuffer.mOffset });
  1019. ioBuffer.mMemory = VK_NULL_HANDLE;
  1020. }
  1021. unique_ptr<ConstantBufferVK> RendererVK::CreateConstantBuffer(VkDeviceSize inBufferSize)
  1022. {
  1023. return make_unique<ConstantBufferVK>(this, inBufferSize);
  1024. }
  1025. VkImageView RendererVK::CreateImageView(VkImage inImage, VkFormat inFormat, VkImageAspectFlags inAspectFlags)
  1026. {
  1027. VkImageViewCreateInfo view_info = {};
  1028. view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
  1029. view_info.image = inImage;
  1030. view_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
  1031. view_info.format = inFormat;
  1032. view_info.subresourceRange.aspectMask = inAspectFlags;
  1033. view_info.subresourceRange.levelCount = 1;
  1034. view_info.subresourceRange.layerCount = 1;
  1035. VkImageView image_view;
  1036. FatalErrorIfFailed(vkCreateImageView(mDevice, &view_info, nullptr, &image_view));
  1037. return image_view;
  1038. }
  1039. void RendererVK::CreateImage(uint32 inWidth, uint32 inHeight, VkFormat inFormat, VkImageTiling inTiling, VkImageUsageFlags inUsage, VkMemoryPropertyFlags inProperties, VkImage &outImage, VkDeviceMemory &outMemory)
  1040. {
  1041. VkImageCreateInfo image_info = {};
  1042. image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
  1043. image_info.imageType = VK_IMAGE_TYPE_2D;
  1044. image_info.extent.width = inWidth;
  1045. image_info.extent.height = inHeight;
  1046. image_info.extent.depth = 1;
  1047. image_info.mipLevels = 1;
  1048. image_info.arrayLayers = 1;
  1049. image_info.format = inFormat;
  1050. image_info.tiling = inTiling;
  1051. image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
  1052. image_info.usage = inUsage;
  1053. image_info.samples = VK_SAMPLE_COUNT_1_BIT;
  1054. image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
  1055. FatalErrorIfFailed(vkCreateImage(mDevice, &image_info, nullptr, &outImage));
  1056. VkMemoryRequirements mem_requirements;
  1057. vkGetImageMemoryRequirements(mDevice, outImage, &mem_requirements);
  1058. AllocateMemory(mem_requirements.size, mem_requirements.memoryTypeBits, inProperties, outMemory);
  1059. vkBindImageMemory(mDevice, outImage, outMemory, 0);
  1060. }
  1061. void RendererVK::DestroyImage(VkImage inImage, VkDeviceMemory inMemory)
  1062. {
  1063. VkMemoryRequirements mem_requirements;
  1064. vkGetImageMemoryRequirements(mDevice, inImage, &mem_requirements);
  1065. vkDestroyImage(mDevice, inImage, nullptr);
  1066. FreeMemory(inMemory, mem_requirements.size);
  1067. }
  1068. void RendererVK::UpdateViewPortAndScissorRect(uint32 inWidth, uint32 inHeight)
  1069. {
  1070. VkCommandBuffer command_buffer = GetCommandBuffer();
  1071. // Update the view port rect
  1072. VkViewport viewport = {};
  1073. viewport.x = 0.0f;
  1074. viewport.y = 0.0f;
  1075. viewport.width = (float)inWidth;
  1076. viewport.height = (float)inHeight;
  1077. viewport.minDepth = 0.0f;
  1078. viewport.maxDepth = 1.0f;
  1079. vkCmdSetViewport(command_buffer, 0, 1, &viewport);
  1080. // Update the scissor rect
  1081. VkRect2D scissor = {};
  1082. scissor.extent = { inWidth, inHeight };
  1083. vkCmdSetScissor(command_buffer, 0, 1, &scissor);
  1084. }
  1085. #ifdef JPH_ENABLE_VULKAN
  1086. Renderer *Renderer::sCreate()
  1087. {
  1088. return new RendererVK;
  1089. }
  1090. #endif