RendererVK.cpp 46 KB

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